修改Django formset中的一个表单实例?

时间:2014-03-11 16:12:40

标签: django forms django-forms

我有一个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

1 个答案:

答案 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的实施细节。)