Django formsets:首先要求吗?

mpe*_*pen 35 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()
Run Code Online (Sandbox Code Playgroud)

我的模板看起来像这样:

    <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>
Run Code Online (Sandbox Code Playgroud)

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

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

来自文档:

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

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

是否有一些我可以改变的属性,至少需要一个表格?

mpe*_*pen 69

找到更好的解决方案:

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

然后像这样创建你的formset:

MyFormSet = formset_factory(MyForm, formset=RequiredFormSet)
Run Code Online (Sandbox Code Playgroud)

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

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

  • 这是 Django 中最烦人的部分之一的解决方案,无法解释为什么这不是文档的一部分 (2认同)

Ane*_*pic 28

Django 1.7中的新功能:您可以使用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)
Run Code Online (Sandbox Code Playgroud)


mpe*_*pen 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.') 
Run Code Online (Sandbox Code Playgroud)

只有"问题"是如果有0个表单,那么该clean方法似乎根本没有被调用,所以我不知道如何检查是否有0.真的......这应该永远不会发生(除了我的JS有一个错误,允许你删除所有表格).