12

我真的发现 django 表单集令人困惑。

我对以下我不太了解的概念特别有疑问:

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

谈论代码试图太聪明。这到底是什么意思?为什么我什至想要那个?

然后,试图理解之前的概念,我看到了人们

在所需的表单集中制作表单。

这是另一个我无法理解的概念。什么是表单集中的必填表单,为什么我必须制作必填表单?再次没有记录的东西。

然后谈到我的实际问题,其他人似乎也遇到过,但他们无法真正解释为什么他们以他们修复它的方式修复它。

为什么在下面的示例中,表单集是有效的,而具有相同输入的单个表单将是无效的?

import django
class MyForm(django.forms.Form):
    start = django.forms.DateField()
    end = django.forms.DateField()

data =  {
    'form-TOTAL_FORMS': '1',
    'form-MAX_NUM_FORMS': '',
    'form-INITIAL_FORMS': '0',
    'form-0-start': '',
    'form-0-end': '',
}

MyFormSet = formset_factory(MyForm)
formset = MyFormSet(data)
#fee_forms[0].empty_permitted = False

print formset.is_valid()
# --- returns True ---
print formset.errors

f = MyForm({'start': '', 'end': ''})
print f.is_valid()
# --- returns False ---
print f.errors

将 empty_permitted 设置为 False 似乎给了我预期的结果(这是由于缺少“开始”和“结束”而导致表单集无效)。这是另一个未记录的功能...

有人愿意花点时间解释吗?

谢谢

4

1 回答 1

22

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

谈论代码试图太聪明。这应该是什么意思?为什么我什至想要那个?

这似乎意味着——正如你所计算的——由表单集(extra=N在你的例子中)创建的“额外”表单已empty_permitted设置为True. 看一眼django/forms/formsets.py就会发生这种情况。

formset[0].empty_permitted表示如果formset[0].has_changed() == False,则不进行进一步的处理/验证。同样,您可以在forms/forms.py.

为了防止这种情况一篇博客文章建议定义一个自定义表单集以用于modelformset_factory(或inlineformset_factory)其中设置empty_permitted = False

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

我没有测试过这个,但它看起来是合法的。

至于为什么有人可能想要这个,它使使用 django-dynamic-formset变得更简单——你可以发送数据,form-0并且form-2假设form-1是一个额外的表单(没有链接到模型数据),Django 不会抱怨。如果默认empty_permitted情况False下,您将不得不担心在您自己的代码中跳过空白表单,或者在 Javascript 中重新索引内容。

于 2013-06-01T23:05:10.703 回答