Django的formsets:首先要求?
这些表单正在展现我想要的完全相反的行为。
我的观点是这样设置的:
def post(request): # TODO: handle vehicle formset VehicleFormSetFactory = formset_factory(VehicleForm, extra=1) if request.POST: vehicles_formset = VehicleFormSetFactory(request.POST) else: vehicles_formset = VehicleFormSetFactory()
我的模板看起来像这样:
<div id="vehicle_forms"> {{ vehicles_formset.management_form }} {% for form in vehicles_formset.forms %} <h4>Vehicle {{forloop.counter}}</h4> <table> {% include "form.html" %} </table> {% endfor %} </div>
这样它最初只生成1个表格,就像我想要的那样。 但是我想要一个forms是必需的!
当我dynamic地添加空白表单与JavaScript和vehicles_formset.empty_form
所有这些额外的forms是必需的,我不想要的。
从文档:
formset足够聪明,可以忽略没有改变的多余的表单。
这是第一种forms展示的行为(不是我想要的),而不是额外forms展示的行为(我想要的)。
是否有一些属性,我可以改变,至less使一个表格所需?
find更好的解决scheme:
class RequiredFormSet(BaseFormSet): def __init__(self, *args, **kwargs): super(RequiredFormSet, self).__init__(*args, **kwargs) for form in self.forms: form.empty_permitted = False
然后像这样创build你的formset:
MyFormSet = formset_factory(MyForm, formset=RequiredFormSet)
我真的不知道为什么这不是一个开始的select…但是,无论如何。 我的生活只花了几个小时才弄清楚。
这将使所有的forms要求。 您可以通过将self.forms[0].empty_permitted
为False
来创build所需的第一个。
Django 1.7新增function:您可以使用formset_factory指定此行为
https://docs.djangoproject.com/en/1.8/topics/forms/formsets/#validate-min
VehicleFormSetFactory = formset_factory(VehicleForm, min_num=1, validate_min=True, extra=1)
那么…这使得所需的第一个forms。
class RequiredFormSet(BaseFormSet): def clean(self): if any(self.errors): return if not self.forms[0].has_changed(): raise forms.ValidationError('Please add at least one vehicle.')
只有“问题”是,如果有0个forms,那么clean
方法似乎根本不会被调用,所以我不知道如何检查是否有0。真的…这应该永远不会发生虽然除了我的JS有一个bug,允许你删除所有的表单)。
哦,我想我明白了。 尝试这个:
from django.forms.formsets import BaseFormSet, formset_factory class OneExtraRequiredFormSet(BaseFormSet): def initial_form_count(self): return max(super(OneExtraRequiredFormSet,self).initial_form_count() - 1,0) VehicleFormSetFactory = formset_factory(VehicleForm, formset=OneExtraRequiredFormSet, extra=1)
==下面的原始答案==
当你说“至less需要一个表单”时,我认为你的意思是“只需要一个额外的表单,而不pipe通过JavaScript添加了多less个表单”。
您需要在页面上隐藏input,其中包含通过javascript添加的表单的数量,然后使用该数字减1作为要作为extra
属性传递给您的formsets构造函数的值。