Django formsets:首先要求吗?

时间:2010-03-09 03:52:22

标签: python django django-forms

这些表单集正好表现出我想要的相反行为。

我的观点设置如下:

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>

这样它最初只生成一个表单,就像我想要的那样。但是我想要一个表格!

当我使用JavaScript和vehicles_formset.empty_form动态添加空白表单时,所有这些额外的表单都是必需的,这是我不想要的。

来自文档:

  

formset足够聪明,可以忽略未更改的额外表单。

这是第一种形式展示的行为(不是我想要的),而不是额外形式展示的行为(我想要的)。

是否有一些属性我可以更改为至少需要一个表单?

3 个答案:

答案 0 :(得分:68)

找到了更好的解决方案:

class RequiredFormSet(BaseFormSet):
    def __init__(self, *args, **kwargs):
        super(RequiredFormSet, self).__init__(*args, **kwargs)
        for form in self.forms:
            form.empty_permitted = False

然后像这样创建你的formset:

MyFormSet = formset_factory(MyForm, formset=RequiredFormSet)

真的不知道为什么这不是一个开头的选择......但是,无论如何。我花了几个小时的时间才弄明白。

这将使所有形式成为必需。您可以通过将self.forms[0].empty_permitted设置为False来完成所需的第一个。

答案 1 :(得分:10)

嗯......这需要第一种形式。

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个表单,那么clean方法似乎根本没有被调用,所以我不知道如何检查是否有0.真的.. 。这应该永远不会发生(除了我的JS有一个错误,允许你删除所有表格)。

答案 2 :(得分:2)

哦,我想我明白了。试试这个:

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)

==以下原始答案==

当你说“至少需要一个表格”时,我认为你的意思是“只需要一个额外的表格,无论通过javascript添加了多少表格”。

您需要在页面上隐藏输入,其中包含通过javascript添加的表单数量,然后使用该数字减1作为extra属性传入的值你的formset构造函数。