Django Forms校验无论字段是否为空均抛ValidationError解决办法
问题原因
你写的校验逻辑始终触发报错,是两个代码错误叠加导致的:
- 第一,Django表单自动生成的
BooleanField默认required=True,该规则下只有复选框被勾选(值为True)才能通过字段级前置校验;未勾选时字段校验直接失败,不会被放入cleaned_data字典,你用get("use_for_car")取值永远拿到None,自然每次都会触发你写的校验报错。 - 第二,
clean()是表单全局校验方法,规范要求必须返回全量的cleaned_data字典,你当前代码最后返回的是未定义的变量use_for_registrations,就算前面的校验判断通过,运行到return行也会直接抛错。
另外补充一个基础逻辑:你当前模型层的use_for_car是普通BooleanField,且没有设置null=True,本身就不支持存储None值,未勾选复选框时会被自动解析为False,根本不会出现值为None的情况。
修复方案
根据你的业务场景二选一调整即可:
场景1:只需要允许用户勾选/不勾选,不区分「未选择」和「选了否」
这是最常见的场景,直接修改forms.py代码即可:
from django.core.exceptions import ValidationError from django import forms from . import models class CheckForm(forms.ModelForm): translated_names = TranslationField() # 重写字段,设置required=False,允许不勾选的情况通过字段级校验 use_for_car = forms.BooleanField(required=False) def clean(self): cleaned_data = super().clean() # 只有当前置校验失败、字段不存在于cleaned_data时才判定为非法输入 if "use_for_car" not in cleaned_data: raise ValidationError("Use For Car NEED TO BE FILLED ") # 必须返回全量cleaned_data,不要返回未定义变量 return cleaned_data class Meta: fields = "__all__" model = models.Check
场景2:需要强制用户主动选择,区分「未选择」和「选了否」
这种场景下None代表用户未做选择,True/False代表用户明确选择结果,需要同步修改模型和表单:
- 修改models.py,允许字段存NULL:
class Check(models.Model): # Django3.1+ 推荐用BooleanField(null=True)替代旧版NullBooleanField use_for_car = models.BooleanField(null=True, default=None) - 修改forms.py,对应字段允许空值:
from django.core.exceptions import ValidationError from django import forms from . import models class CheckForm(forms.ModelForm): translated_names = TranslationField() use_for_car = forms.BooleanField(required=False) def clean(self): cleaned_data = super().clean() use_for_car = cleaned_data.get("use_for_car") if use_for_car is None: raise ValidationError("Use For Car NEED TO BE FILLED ") return cleaned_data class Meta: fields = "__all__" model = models.Check
注意:这种场景下不要用默认的复选框渲染控件,换成下拉选择(选项为「请选择/是/否」),否则复选框未勾选时依然会被自动解析为
False,拿不到None值。
内容的提问来源于stack exchange,提问作者Yen
相关产品推荐
相关产品推荐

