Django 使用 ModelForm 覆盖 __init__ 表单方法
Django override __init__ form method using ModelForm
我有一个外键 (zone_set
) 作为表单中的选择字段。它应该只显示当前项目的 zone_set
。如您所见,情况并非如此,因为它显示的 zone_set:
I belong to an other project, I should not be displayed here
不属于当前项目。
请帮忙!
这是我的表格,但它不起作用
class ODMatrixForm(forms.ModelForm):
class Meta:
model = ODMatrix
# fields = '__all__'
exclude = ('size', 'locked',)
def __init__(self, current_project=None, *args, **kwargs):
super().__init__(*args, **kwargs)
if current_project:
queryset = ZoneSet.objects.filter(project=current_project)
self.fields['zone_set'].queryset = queryset
创建 ODMatrix 的视图
def create_od_matrix(request, pk):
"""A roadnetwork depends on a project. It
must be created inside the project"""
current_project = Project.objects.get(id=pk)
form = ODMatrixForm(initial={'project': current_project})
if request.method == 'POST':
print(request)
od_matrix = ODMatrix(project=current_project)
# form = ODMatrixForm(request.POST, instance=od_marix)
form = ODMatrixForm(data=request.POST, instance=od_matrix)
if form.is_valid():
form.save()
messages.success(request, "OD matrix cessfully created")
return redirect('od_matrix_details', od_matrix.pk)
context = {
'project': current_project,
'form': form}
return render(request, 'form.html', context)
您创建了 __init__
作为 Meta
class 的构造函数,这应该是 ODMatrixForm
的构造函数,所以:
class ODMatrixForm(forms.ModelForm):
# 🖟 part of ODMatrixForm, not Meta
def <strong>__init__</strong>(self, current_project=None, *args, **kwargs):
super().__init__(*args, **kwargs)
if current_project:
self.fields['zone_set'].queryset = ZoneSet.objects.filter(
project=current_project
)
class Meta:
model = ODMatrix
# fields = '__all__'
exclude = ('size', 'locked',)
在视图中,构造ODMatrixForm
对象时需要传递current_project
:
from django.shortcuts import get_object_or_404
def create_od_matrix(request, pk):
current_project = get_object_or_404(Project, pk=pk)
if request.method == 'POST':
form = ODMatrixForm(<strong>current_project</strong>, request.POST, request.FILES)
if form.is_valid():
form.instance.project = current_project
form.save()
messages.success(request, 'OD matrix cessfully created')
return redirect('od_matrix_details', od_matrix.pk)
else:
form = ODMatrixForm(<strong>current_project=current_project</strong>)
context = {
'project': current_project,
'form': form
}
return render(request, 'form.html', context)
Note: It is often better to use get_object_or_404(…)
[Django-doc],
then to use .get(…)
[Django-doc] directly. In case the object does not exists,
for example because the user altered the URL themselves, the get_object_or_404(…)
will result in returning a HTTP 404 Not Found response, whereas using
.get(…)
will result in a HTTP 500 Server Error.
我有一个外键 (zone_set
) 作为表单中的选择字段。它应该只显示当前项目的 zone_set
。如您所见,情况并非如此,因为它显示的 zone_set:
I belong to an other project, I should not be displayed here
不属于当前项目。
请帮忙!
这是我的表格,但它不起作用
class ODMatrixForm(forms.ModelForm):
class Meta:
model = ODMatrix
# fields = '__all__'
exclude = ('size', 'locked',)
def __init__(self, current_project=None, *args, **kwargs):
super().__init__(*args, **kwargs)
if current_project:
queryset = ZoneSet.objects.filter(project=current_project)
self.fields['zone_set'].queryset = queryset
创建 ODMatrix 的视图
def create_od_matrix(request, pk):
"""A roadnetwork depends on a project. It
must be created inside the project"""
current_project = Project.objects.get(id=pk)
form = ODMatrixForm(initial={'project': current_project})
if request.method == 'POST':
print(request)
od_matrix = ODMatrix(project=current_project)
# form = ODMatrixForm(request.POST, instance=od_marix)
form = ODMatrixForm(data=request.POST, instance=od_matrix)
if form.is_valid():
form.save()
messages.success(request, "OD matrix cessfully created")
return redirect('od_matrix_details', od_matrix.pk)
context = {
'project': current_project,
'form': form}
return render(request, 'form.html', context)
您创建了 __init__
作为 Meta
class 的构造函数,这应该是 ODMatrixForm
的构造函数,所以:
class ODMatrixForm(forms.ModelForm):
# 🖟 part of ODMatrixForm, not Meta
def <strong>__init__</strong>(self, current_project=None, *args, **kwargs):
super().__init__(*args, **kwargs)
if current_project:
self.fields['zone_set'].queryset = ZoneSet.objects.filter(
project=current_project
)
class Meta:
model = ODMatrix
# fields = '__all__'
exclude = ('size', 'locked',)
在视图中,构造ODMatrixForm
对象时需要传递current_project
:
from django.shortcuts import get_object_or_404
def create_od_matrix(request, pk):
current_project = get_object_or_404(Project, pk=pk)
if request.method == 'POST':
form = ODMatrixForm(<strong>current_project</strong>, request.POST, request.FILES)
if form.is_valid():
form.instance.project = current_project
form.save()
messages.success(request, 'OD matrix cessfully created')
return redirect('od_matrix_details', od_matrix.pk)
else:
form = ODMatrixForm(<strong>current_project=current_project</strong>)
context = {
'project': current_project,
'form': form
}
return render(request, 'form.html', context)
Note: It is often better to use
get_object_or_404(…)
[Django-doc], then to use.get(…)
[Django-doc] directly. In case the object does not exists, for example because the user altered the URL themselves, theget_object_or_404(…)
will result in returning a HTTP 404 Not Found response, whereas using.get(…)
will result in a HTTP 500 Server Error.