4

我正在使用 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 外壳:

>>> 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正确验证其他类型的字段。文档表明默认情况下所有字段都是必需的,但在不存在布尔字段键的情况下is_valid返回。True

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

4

1 回答 1

7

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

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

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

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

于 2013-10-11T22:53:33.607 回答