django ModelForm似乎没有验证BooleanField

时间:2013-10-11 22:35:07

标签: django validation django-forms

我正在使用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并添加此检查,以便它也可以重复用于其他模型吗?

1 个答案:

答案 0 :(得分:7)

事实证明(来自代码检查;文档没有说明)模型BooleanFieldblank=True方法中自动设置了__init__,从而使自动创建的模型形式字段不需要。这在考虑时是有意义的(虚假计数为空白,因此BooleanField需要它是真的)但是当你阅读文档时它并不明显。

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

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

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