Django 3.2单字段验证中cleaned_data含多字段的疑问
Django 3.2 ModelForm clean_方法中cleaned_data包含其他字段的原因
问题背景
作为Django新手,正在学习表单验证。使用Django 3.2版本,定义了如下模型:
class Personen(models.Model): DEUTSCHLAND = 'DE' SCHWEIZ = "CH" ÖSTERREICH = "AT" ENGLAND = "UK" NATION_CHOICES = [ (DEUTSCHLAND, "Deutschland"), (SCHWEIZ, "Schweiz"), (ÖSTERREICH, "Österreich"), (ENGLAND, "England"), ] vorname = models.CharField(max_length=200) nachname = models.CharField(max_length=200) username = models.CharField(max_length=200) stadt = models.CharField(max_length=15, validators=[ validate_nation_regexval], null=True) nationalität = models.CharField( max_length=2, choices=NATION_CHOICES, default=DEUTSCHLAND) biere = models.ManyToManyField("Bier", through="PersonenBier") def __str__(self): return self.username
基于该模型创建PersonenForm,并为username字段编写了字段级验证方法:
class PersonenForm(ModelForm): class Meta: model = Personen fields = '__all__' def clean_username(self): print(self.cleaned_data) username_passed = self.cleaned_data["username"] username_req = "user_" if not username_req in username_passed: raise ValidationError("Ungültig") return username_passed
功能正常,但疑惑:原本预期cleaned_data字典仅包含username字段,为何其中还存在vorname和nachname字段?
解答
这是因为Django表单的字段级验证是按模型中字段的定义顺序依次执行的,cleaned_data是一个逐步累积的验证结果字典,而非仅包含当前正在处理的字段。
具体到你的场景:
- 模型中字段定义顺序为
vorname→nachname→username - 表单验证时,会按这个顺序逐个处理字段:
- 先验证
vorname:作为必填CharField,只要提交的数据符合长度要求且非空,就会通过基础验证,将有效值存入cleaned_data - 接着验证
nachname:同样通过默认验证后,值也被加入cleaned_data - 最后执行
clean_username方法:此时cleaned_data已经包含了前面两个验证通过的字段值,再加上当前username的基础验证值(前提是username先通过了非空、长度合规的基础验证)
- 先验证
如果某个字段验证失败(比如vorname未填写),它的值就不会被加入cleaned_data,此时你在clean_username中打印的cleaned_data就不会包含该字段。
简单总结:cleaned_data会逐步收集所有已经通过验证的字段值,直到整个表单的字段级验证全部完成。
内容的提问来源于stack exchange,提问作者mafe68
相关产品推荐
相关产品推荐

