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_permittedFalse来创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构造函数的值。