Django 和空表单集是有效的

Posted

技术标签:

【中文标题】Django 和空表单集是有效的【英文标题】:Django and empty formset are valid 【发布时间】:2011-05-27 18:02:54 【问题描述】:

我的表单集有点问题。

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

#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))

问题是当我提交页面时,空表单“自动”有效(未经检查), 但如果我在一张表格中填写一个字段,检查就会生效。

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

谢谢。

【问题讨论】:

【参考方案1】:

简单更好。由于 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()

【讨论】:

【参考方案2】:

@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)

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

【讨论】:

由于 empty_permittedinit 方法中的参数,您可以在调用中使用 form_kwargs 并避免在你的子类示例。 facility_formset = modelformset_factory(Facility, form=FacilityForm)(request.POST, form_kwargs='empty_permitted': False) 请注意 form_kwargs 在 django 版本 1.9+ 中可用【参考方案3】:

基于“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找到描述

【讨论】:

【参考方案4】:

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

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

【讨论】:

谢谢,我使用您的解决方案解决了我的问题:空表单不应该验证。看我的例子。

以上是关于Django 和空表单集是有效的的主要内容,如果未能解决你的问题,请参考以下文章

为啥 django 模型的空白和空值不同的选项?

为啥 django 模型的空白和空值不同的选项?

AngularJS 表单和空/空值

检查日期是不是对选定的月份有效 Django 表单

Django 表单和引导程序 - 添加小部件有效但不完全

使用有效实例设置后 django 表单无效