django formsets confusion(validation,required,empty_permitted) [英] django formsets confusion (validation, required, empty_permitted)
问题描述
我真的很难发现django formets令人困惑。
$ b
表单非常聪明,可以忽略不是
更改的额外表单。
谈论代码试图太聪明这是什么意思呢?为什么还要这样?
然后,试图理解以前的概念,我看到人们
在所需的表单中创建表单。
这是另一个概念,我无法得到这个悬念。一个表单中需要的表单是什么,为什么必须填写表单?再一次没有记录的东西。
然后来到我的实际问题,哪些其他人似乎有,但他们不能真正解释为什么他们已经修复了他们已经修复了它。
为什么在以下示例中,表单是有效的,而具有相同输入的单个表单将无效?
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()
#---返回True ---
print formset.errors
f = MyForm({'start':'','end':''} )
print f.is_valid()
#---返回False ---
打印f.errors
将empty_permitted设置为False似乎给我预期的结果(由于缺少开始和结束,表单集无效)。这是另一个无证的功能...
有没有人会有时间解释?
谢谢
表单非常聪明,可以忽略未更改的额外表单
谈论代码尝试太聪明。这是什么意思呢?为什么我甚至想要这个?
这似乎意味着 - 在你制定出来 - 表单创建的额外在您的示例中 extra = N
将 empty_permitted
设置为 True
。 瞥一下 django / forms / formsets.py
看到这种情况。
formset [0]。 empty_permitted
意味着如果 formset [0] .has_changed()== False
,则不进行进一步的处理/验证。再次,您可以看到这一点在行动中 forms / forms.py
。
为了防止这种 a href =http://www.kevinbrolly.co.uk/blog/django-model-formsets-not-validating/ =noreferrer>一篇博客帖子建议定义一个自定义表单集 modelformset_factory
(或 inlineformset_factory
)设置 empty_permitted = False
class MyModelFormSet(BaseModelFormSet):
pre>
def __init __(self,* args,** kwargs):
super(MyModelFormSet,self).__ init __(* args,** kwargs)
在self.forms中的表单:
form.empty_permitted = False
我没有测试过,但看起来很合法。
至于为什么任何人都想要这个,它使用
django-dynamic-formset
更简单 - 您可以发送form-0
和form-2
,假设form-1
是一个额外的表单( ie 没有链接到模型数据),Django不会抱怨。默认情况下,如果empty_permitted
False
,则必须担心在自己的代码中跳过空白表单,或在Javascript中重新编号。I am really finding the django formsets confusing.
I am especially having problems with the following concepts which I don't really understand:
The formset is smart enough to ignore extra forms that were not changed.
Talking about code trying to be too smart. What is this supposed to mean exactly ? Why would I even want that ?
Then, trying to understand the previous concept, I see people
making forms in the formsets required.
This is another concept I can't get the hang of. What is a required form in a formset and why do I have to make a form required ? Again something not documented.
Then coming to my actual problem, which other people seem to have had, but they can't really explain why they've fixed it the way they've fixed it.
Why in the following example, the formset is valid, while an individual form with the same input will be invalid ?
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
Setting empty_permitted to False seems to give the expected results for me (which is for the formset to be invalid due to missing 'start' and 'end'). This is another undocumented feature ...
Would anybody spare some time to explain ?
Thank you
解决方案The formset is smart enough to ignore extra forms that were not changed.
Talking about code trying to be too smart. What is this supposed to mean exactly? Why would I even want that?
It seems to mean — as you worked out — that "extra" forms created by the formset (with
extra=N
in your example) haveempty_permitted
set toTrue
. Have a glance atdjango/forms/formsets.py
to see this happening.
formset[0].empty_permitted
means that ifformset[0].has_changed() == False
, no further processing/validation is done. Again, you can see this in action informs/forms.py
.To prevent this, a blog post suggests defining a custom formset to use in
modelformset_factory
(orinlineformset_factory
) which setsempty_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
I haven't tested this, but it looks legit.
As to why anyone might want this, it makes using
django-dynamic-formset
much simpler — you can send data forform-0
andform-2
and, assumingform-1
was an extra form (i.e. not linked to model data), Django won't complain. Ifempty_permitted
wereFalse
by default, you'd have to worry about skipping the blank form in your own code, or reindexing things in Javascript.这篇关于django formsets confusion(validation,required,empty_permitted)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!