Django formsets:需要先生成?

2024-05-13 23:53:19 发布

您现在位置:Python中文网/ 问答频道 /正文

这些表单集正好显示了我想要的相反的行为。

我的观点是这样的:

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动态添加空白表单时,所有这些额外的表单都是必需的,这是我不需要的。

从文档中:

The formset is smart enough to ignore extra forms that were not changed.

这是第一个表单显示的行为(不是我想要的),但不是额外表单显示的行为(我确实想要的)。

是否有一些属性可以更改为至少使成为必需的表单?


Tags: divform表单requestdeftableformspost
3条回答

找到更好的解决方案:

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

然后按如下方式创建表单集:

MyFormSet = formset_factory(MyForm, formset=RequiredFormSet)

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

这将使所需的所有表格。通过将self.forms[0].empty_permitted设置为False,您可以只生成所需的第一个。

嗯。。。这就需要第一个表单。

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中有一个bug,允许您删除所有表单)。

Django 1.7中的新特性:可以使用formset工厂指定此行为

https://docs.djangoproject.com/en/1.8/topics/forms/formsets/#validate-min

VehicleFormSetFactory = formset_factory(VehicleForm, min_num=1, validate_min=True, extra=1)

相关问题 更多 >