【问题标题】:django ModelForm doesn't seem to validate BooleanFielddjango ModelForm 似乎没有验证 BooleanField
【发布时间】:2013-10-20 03:12:28
【问题描述】:

我正在使用 django 1.5.4

这是我面临的问题的一个最小示例。

型号:

#models.py
from django.db import models

class SampleModel(models.Model):
    spam = models.BooleanField()

形式:

#forms.py
from django.forms import ModelForm
from .models import SampleModel

class SampleModelForm(ModelForm):
    class Meta:
        model = SampleModel
        fields = ('spam', )

来自 django shell:

>>> data = {} #intentionally blank
>>> form = SampleModelForm(data)
>>> is_valid = form.is_valid() #is_valid is True
>>> form.save() # model instance is created with "spam" set to False by default.

我是否错误地验证了表单? form.is_valid 正确验证其他类型的字段。 docs 表示默认情况下所有字段都是必需的,但 is_valid 返回 True 而没有布尔字段键。

我需要确保输入数据中存在布尔字段。 截至目前,我正在手动检查该字段是否存在并且类型为bool。您认为我应该覆盖form.is_valid 并添加此检查,以便它也可以用于其他模型吗?

【问题讨论】:

    标签: django validation django-forms


    【解决方案1】:

    事实证明(来自代码检查;文档没有说)BooleanFields 模型在其__init__ 方法中自动设置了blank=True,因此不需要自动创建的模型表单字段。考虑到这一点是有道理的(False 算作空白,所以BooleanFields 需要它是真实的)但是当您阅读文档时并不明显。

    如果您希望它被要求为True,则通常的表单字段覆盖适用 - 自己声明该字段或在验证之前将其required 属性设置为True(我通常使用表单的@987654328 @ 方法)。如果您希望它允许TrueFalse 但不允许Python None,那就更难了。

    具体来说,BooleanField 的标准小部件是一个复选框。浏览器不会为未选中的复选框提交任何内容,因此复选框小部件将提交中缺少该字段视为False。没有办法区分用户没有选择复选框和输入真的很糟糕的情况。您可以使用不同的小部件(例如,RadioSelect)至少使浏览器可以为False 提交内容,但您仍然遇到BooleanFieldto_python 方法将其转换为在验证之前将值设置为 boolean,因此您必须进行子类化和覆盖。

    幸运的是,验证码不会将False 视为空,因此如果您这样做,您将能够设置required=True,并且不需要自定义清理方法。

    【讨论】:

    • 谢谢!在__init__ 中设置self.fields['spam'].required = True 有效。我想要 JSON API 的这种行为。