Django模型验证机制详解:full_clean与字段校验流程
本文深入解析Django框架中模型对象的验证机制,详细阐述Model.clean_fields、Model.clean及Model.validate_unique三个核心方法的执行顺序与功能。通过代码示例说明如何手动调用full_clean进行完整校验,以及如何处理字段级与非字段级的ValidationError异常,帮助开发者在ModelForm之外实现精准的模型数据验证。
Django模型验证概述
本文详细介绍Django框架中模型对象验证的具体实现方式,旨在为开发者提供清晰的参考。
模型对象的验证流程
对模型进行完整验证包含以下三个关键步骤:
- 字段级验证 —— 调用Model.clean_fields()方法
- 模型完整性验证 —— 调用Model.clean()方法
- 唯一性约束验证 —— 调用Model.validate_unique()方法
full_clean方法执行机制
当执行模型的full_clean()方法时,上述三个步骤将依次执行。在使用ModelForm时,is_valid()方法会自动对所有字段执行这些验证逻辑。若开发者计划自行处理验证过程中产生的错误,或者希望从ModelForm中移除某些无需验证的字段,则可以直接调用模型的full_clean()方法以触发验证。
Model.full_clean(exclude=None, validate_unique=True)
该方法按固定顺序依次调用Model.clean_fields()、Model.clean(),并在validate_unique参数为True时调用Model.validate_unique()。若验证失败,将抛出ValidationError异常,其message_dict属性包含所有步骤的错误信息。可选的exclude参数用于指定一组字段名称,这些字段将不参与验证和清除过程。ModelForm利用此参数排除未出现在表单中的字段,从而避免对这些用户无法修改的字段进行验证。需要注意的是,调用模型的save()方法时,并不会自动执行full_clean()。若需对手动创建的模型实例进行一步验证,必须显式调用该方法。示例如下:
from django.core.exceptions import ValidationError
try:
article.full_clean()
except ValidationError as e:
# Do something based on the errors contained in e.message_dict.
# Display them to a user, or handle them programmatically.
pass
字段级验证:clean_fields
full_clean()的第一步是验证每个字段的有效性。
Model.clean_fields(exclude=None)
该方法负责验证模型的所有字段。通过可选的exclude参数,可以指定一组字段名称将其排除在验证之外。若任一字段验证失败,将抛出ValidationError异常。
模型级验证:clean方法
full_clean()方法的第二步是调用Model.clean()。如需实现自定义的模型验证逻辑,应重写此方法。
Model.clean()
此方法用于提供自定义的模型验证逻辑,并可修改模型属性。例如,可用于自动为字段赋值,或处理多个字段间的联合验证:
import datetime
from django.core.exceptions import ValidationError
from django.db import models
class Article(models.Model):
...
def clean(self):
# Don't allow draft entries to have a pub_date.
if self.status == 'draft' and self.pub_date is not None:
raise ValidationError('Draft entries may not have a publication date.')
# Set the pub_date for published items if it hasn't been set already.
if self.status == 'published' and self.pub_date is None:
self.pub_date = datetime.date.today()
与Model.full_clean()类似,直接调用模型的save()方法时,不会触发clean()方法的执行。
在上述示例中,Model.clean()抛出的ValidationError异常通过字符串实例化,因此该错误将被存入特殊的错误字典键NON_FIELD_ERRORS中。该键用于记录整个模型层面的错误,而非特定字段的错误:
from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
try:
article.full_clean()
except ValidationError as e:
non_field_errors = e.message_dict[NON_FIELD_ERRORS]
若需针对特定字段抛出异常,可使用字典实例化ValidationError,其中字典的键为字段名称。我们可以更新前例,仅针对pub_date字段抛出异常:
class Article(models.Model):
...
def clean(self):
# Don't allow draft entries to have a pub_date.
if self.status == 'draft' and self.pub_date is not None:
raise ValidationError({'pub_date': 'Draft entries may not have a publication date.'})
...
唯一性验证:validate_unique
最后,full_clean()方法负责检查模型的唯一性约束。
Model.validate_unique(exclude=None)
该方法与clean_fields()类似,但侧重于验证模型的所有唯一性约束,而非单个字段的值。可选的exclude参数允许指定一组字段名称,将其排除在验证之外。若验证失败,将抛出ValidationError异常。
注意,若向validate_unique()提供exclude参数,则涉及这些字段的unique_together约束将不再进行检查。
希望本文关于Django框架Python程序设计的验证机制介绍能对您有所帮助。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













