我有一个Django formset,我在其中渲染一个表单的四个实例。 formset中的每个表单都有两个字段,但我希望最后一个(第四个)实例只显示/输入一个字段。我怎么能这样做,还是有更好的方法?我尝试将formset限制为三个字段,并使第四个实例成为自己的形式,但我需要针对formset中的field1
字段验证field1
。我无法看到如何针对同时提交的表单集验证表单。
views.py:
FormSet = formset_factory(MyForm, formset=BaseMyFormSet, extra=4)
html的:
<form action="" method="post">{% csrf_token %}
{{ formset.management_form }}
{{ formset.non_form_errors }}
<div>
{% for form in formset %}
{% for field in form %}
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
{% endfor %}
{% endfor %}
</div>
<p><input type="submit" value="Submit" /></p>
</form>
formset在forms.py中有两个字段:
class MyForm(forms.Form):
# field1
# field2
如何创建它以使formset中的前三个表单有两个字段,但最后一个只包含field1
?
答案 0 :(得分:2)
尝试明确删除views.py中最后一个表单的字段:
def view_func(request):
FormSet = formset_factory(MyForm, formset=BaseMyFormSet, extra=4)
if request.method == 'POST':
formset = FormSet(request.POST, request.FILES)
# assuming this is a required field for the other forms
formset.forms[-1].fields['field2'].required = False
if formset.is_valid():
...
else:
formset = FormSet()
del formset.forms[-1].fields['field2']
return render(request, 'form.html', {'formset': formset})
任何进一步的调整取决于您的表单和验证逻辑。 BaseMyFormSet.clean()
是formset-wide validation的合适位置,听起来您已经有代码在表格中比较field1
。
(从纯粹的意义上讲,让FormSet类完全处理它可能会更好,但这更容易.FormSet代码相当复杂。覆盖BaseFormSet.forms()是有意义的但是@cached_property
位,您参与了最好留给Django的实施细节。)