2010-12-19 69 views
9

我对formset有一点问题。Django和空的formset有效

我必须在页面中显示几个formset,每个formset都有几种形式。 所以我做了这样的事情:

#GET 
for prod in products: 
    ProductFormSet = modelformset_factory(Product,exclude=('date',),extra=prod.amount) 
    formsset.append(ProductFormSet(prefix="prod_%d"%prod.pk)) 

#POST 
for prod in products: 
    ProductFormSet = modelformset_factory(Product,exclude=('date',),extra=prod.amount) 
    formsset.append(ProductFormSet(request.POST,prefix="prod_%d"%prod.pk)) 

问题是,当我提交页面,空瓶形式是“自动”有效(不检查), 但如果我在一个表格一个字段,检查在它上面工作。

我不知道为什么,所以如果有人有一个想法,

谢谢。

回答

19

我在研究另一个问题时遇到了这个问题。在挖掘Django源代码寻找我的问题的解决方案时,我找到了这个问题的答案,所以我将在此处记录它:

当表单被允许具有空值时(这适用于包含的空表单在一个formset中)提交的值没有从最初的值改变,验证被跳过。检查full_clean()方法,在Django /表格/ forms.py(线265在Django 1.2):

# If the form is permitted to be empty, and none of the form data has 
# changed from the initial data, short circuit any validation. 
if self.empty_permitted and not self.has_changed(): 
    return 

我不知道你要找什么样的解决方案(也,这个问题已经是有点过时了),但也许这将有助于未来的人。

+0

谢谢,我用你的解决方案来解决我的问题:空表格不应该验证。看我的例子。 – 2013-01-21 16:53:13

2

基于“formset_factory”的“extra”参数创建的表单将其“empty_permitted”属性设置为True。 (参见:formset.py线123)

# Allow extra forms to be empty. 
    if i >= self.initial_form_count(): 
     defaults['empty_permitted'] = True 

所以看起来更好的方式来使用表单集的“初始”参数,而不是“formset_factory”这个用例的“额外”的参数。

请找到using-initial-data-with-a-formset

10

@Jonas,感谢描述。我用你的描述来解决我的问题。我需要一个表单在空时不验证。 (窗体添加了javascript)

class FacilityForm(forms.ModelForm): 
    class Meta: 
     model = Facility 

    def __init__(self, *arg, **kwarg): 
     super(FacilityForm, self).__init__(*arg, **kwarg) 
     self.empty_permitted = False 


facility_formset = modelformset_factory(Facility, form=FacilityForm)(request.POST) 

它会确保任何显示的表单在提交时不能为空。

+1

由于'empty_permitted'是__init__方法中的参数,因此可以在调用中使用'form_kwargs',并避免在子类示例中创建__init__方法。 'facility_formset = modelformset_factory(facility,form = FacilityForm)(request.POST,form_kwargs = {'empty_permitted':False})' – Bobort 2017-03-06 17:33:32

+0

请注意,form_kwargs在django 1.9+ – 2017-07-18 06:43:25