11

我对表单集有一点问题。

我必须在一个页面中显示几个表单集,每个表单集都有几个表单。所以我做了这样的事情:

#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

4 回答 4

23

我在研究另一个问题时遇到了这个问题。在挖掘 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

我不确定您正在寻找什么样的解决方案(此外,这个问题已经有些过时了),但也许这会对将来的某人有所帮助。

于 2011-03-22T20:54:39.790 回答
16

@乔纳斯,谢谢。我用你的描述来解决我的问题。我需要表单在为空时不进行验证。(用 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)

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

于 2013-01-21T16:50:36.920 回答
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 的“初始”参数而不是“formset_factory”的“额外”参数似乎是更好的方法。

请在using-initial-data-with-a-formset找到说明

于 2012-04-06T06:33:48.670 回答
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()
于 2018-04-12T20:48:44.997 回答