Django和空formset是有效的

时间:2010-12-19 02:49:27

标签: python django formset

我对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))

问题是当我提交页面时,空箱表格“自动”有效(没有支票), 但如果我在一个表格中填写一个字段,则检查就可以了。

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

感谢。

4 个答案:

答案 0 :(得分:21)

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

如果允许表单具有空值(这适用于表单集中包含的空表单),则提交的值未从初始值更改,则会跳过验证。检查django / forms / forms.py中的full_clean()方法(Django 1.2中的第265行):

# 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

我不确定你正在寻找什么样的解决方案(此外,这个问题已经有点过时了)但也许这将有助于未来的人。

答案 1 :(得分: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)

确保所提交的表格在提交时不得为空。

答案 2 :(得分: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的“initial”参数而不是“formset_factory”的“extra”参数。

请在using-initial-data-with-a-formset

找到说明

答案 3 :(得分:0)

简单就是更好。由于Formset是表单列表,您可以迭代此集。

if FormSet(request.POST,).is_valid():
    for form in FormSet:
        # Check if value is empty using value().
        if form['field'].value():
            # this form's field is not empty. Create and save object.
            object = form.save()