django formsets confusion(validation,required,empty_permitted) [英] django formsets confusion (validation, required, empty_permitted)

查看:131
本文介绍了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):
def __init __(self,* args,** kwargs):
super(MyModelFormSet,self).__ init __(* args,** kwargs)
在self.forms中的表单:
form.empty_permitted = False
pre>

我没有测试过,但看起来很合法。



至于为什么任何人都想要这个,它使用
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) have empty_permitted set to True. Have a glance at django/forms/formsets.py to see this happening.

formset[0].empty_permitted means that if formset[0].has_changed() == False, no further processing/validation is done. Again, you can see this in action in forms/forms.py.

To prevent this, a blog post suggests defining a custom formset to use in modelformset_factory (or inlineformset_factory) which sets 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

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 for form-0 and form-2 and, assuming form-1 was an extra form (i.e. not linked to model data), Django won't complain. If empty_permitted were False 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆