django formsets confusion(validation,required,empty_permitted)

时间:2012-12-06 14:09:05

标签: django django-forms

我真的觉得django formsets令人困惑。

我特别遇到以下概念的问题,我并不理解:

  

formset足够聪明,可以忽略不是的额外表单   改变。

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

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

  

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

这是另一个我无法理解的概念。什么是表格中的必填表格,为什么我需要制作表格?再一次没有记录。

接着解决了其他人似乎已经遇到的实际问题,但是他们无法解释为什么他们修复它的方式。

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

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似乎为我提供了预期的结果(由于缺少'start'和'end',formset无效)。这是另一个没有记录的功能......

有人花些时间解释一下吗?

谢谢

1 个答案:

答案 0 :(得分:14)

  
    

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

  
     

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

这似乎意味着 - 当您解决时 - 由formset创建的“额外”表单(在您的示例中为extra=N)将empty_permitted设置为TrueHave a glance at django/forms/formsets.py看到这种情况发生了。

formset[0].empty_permitted表示如果formset[0].has_changed() == False,则不会进行进一步的处理/验证。再次,you can see this in action in forms/forms.py

要阻止此a blog post suggests定义要在设置modelformset_factory的{​​{1}}(或inlineformset_factory)中使用的自定义表单集:

empty_permitted = False

我没有对此进行过测试,但它看似合法。

至于为什么有人想要这个,它会使用 django-dynamic-formset更加简单 - 您可以发送class MyModelFormSet(BaseModelFormSet): def __init__(self, *args, **kwargs): super(MyModelFormSet, self).__init__(*args, **kwargs) for form in self.forms: form.empty_permitted = False form-0的数据,并假设form-2是一个额外的表单(未链接到模型数据),Django不会抱怨。如果form-1默认为empty_permitted,则您必须担心在自己的代码中跳过空白表单,或者在Javascript中重新编制索引。