Django中ValidationError未触发,cleaned_data缺失键问题
问题原因与解决方案
核心原因
Django表单的验证流程是先执行字段级验证(包括你定义的validate_not_past),再执行表单级的clean()方法。当字段级验证抛出ValidationError时,Django会将该错误存入表单的errors字典,同时不会将该字段的值加入cleaned_data。
你当前的clean()方法没有先判断字段是否通过了字段级验证,直接尝试比较start_date和due_date——如果due_date因为validate_not_past验证失败,cleaned_data里就没有这个键,self.cleaned_data.get('due_date')会返回None,自然触发TypeError。
另外,你的clean()方法没有返回cleaned_data,这不符合Django的规范,会导致后续流程无法正确获取验证后的字段数据。
修复代码
修改forms.py中的clean()方法:
class ProjectUpdateForm(ModelForm): start_date = DateField(...) due_date = DateField(label="Due Date", required=True, widget=CustomDatePicker(), validators=[validate_not_past]) def clean(self): # 接收父类clean方法返回的cleaned_data,这是规范写法 cleaned_data = super().clean() start_date = cleaned_data.get('start_date') due_date = cleaned_data.get('due_date') # 先判断两个字段都通过了字段级验证(存在于cleaned_data中),再执行比较 if start_date is not None and due_date is not None: if start_date > due_date: raise ValidationError("Project Start Date cannot be after Project End Date") # 必须返回cleaned_data return cleaned_data
额外说明
- 当字段级验证失败时,表单的
is_valid()会返回False,你可以在视图中通过form.errors获取具体的错误信息(包括validate_not_past抛出的错误),不需要手动捕获异常。 - 始终确保
clean()方法返回cleaned_data,否则表单的验证数据无法正确传递到后续逻辑。
内容的提问来源于stack exchange,提问作者e2718281
相关产品推荐
相关产品推荐

