Django模型验证器介绍与源码分析
Django 是一个高度模块化的 Web 应用框架,其模型层是 Django 中最重要的一部分。模型验证器是 Django 模型层的一项功能,用来验证模型实例的有效性,包括验证模型的字段是否符合规范,是否符合业务逻辑等。本文将详细介绍 Django 模型验证器的用法,以及它的源码分析。
模型验证器的用法
在 Django 中,每个模型都有一个 clean()
方法,用来在模型保存之前进行数据验证。这个方法实际上是一个基于验证器的钩子,你可以通过覆盖它,或者添加更多的验证器来实现自定义的数据验证。
在模型的字段中,每个字段都可以定义一个验证器。这个验证器可以是一个函数、方法或类,用来对字段进行自定义的验证。Django 内置了许多常用的验证器,例如 MaxValueValidator
、MinValueValidator
等等。
下面是一个示例,我们定义一个模型 Person
,其中包含了三个字段,分别是姓名(name)、年龄(age)、邮箱(email),其中年龄(age)字段必须为正整数。
from django.db import models
from django.core.exceptions import ValidationError
def positive_validator(value):
if value < 0:
raise ValidationError('%s 必须是正整数。' % value)
class Person(models.Model):
name = models.CharField(max_length=50)
age = models.PositiveIntegerField(validators=[positive_validator])
email = models.EmailField()
def clean(self):
if self.age < 18:
raise ValidationError('未满18岁不能注册!')
def __str__(self):
return self.name
在上面的代码中,我们定义了 positive_validator
方法,用来验证 age
字段的值是否为正整数。Person
模型中的 age
字段的 validators
参数中传递了这个验证器。除此之外,我们还定义了 clean()
方法,用来验证模型是否满足业务逻辑,例如年龄是否满足条件。如果验证失败,clean()
方法应该抛出 ValidationError
异常,Django 会自动将这个异常捕获并展示给用户。
模型验证器的源码分析
Django 内置的验证器都位于 django.core.validators
模块中。这些验证器的基本形式是一个接受参数的函数或类,并且它们都有一个 __call__
方法,用来实现验证逻辑。
下面是一个 MaxValueValidator
的示例,该验证器用来验证一个值是否小于等于最大值。
class MaxValueValidator:
message = _('Ensure this value is less than or equal to %(limit_value)s.')
code = 'max_value'
def __init__(self, limit_value):
self.limit_value = limit_value
def __call__(self, value):
if value is not None and value > self.limit_value:
raise ValidationError(
self.message,
code=self.code,
params={'limit_value': self.limit_value},
)
在上面的代码中,它首先定义了 message
和 code
两个属性,用来表示验证失败的错误信息和错误码。在 __init__
方法中,它接受一个最大值 limit_value
,这个值会在验证时用到。在 __call__
方法中,它通过比较输入值 value
和最大值 limit_value
的大小来验证是否合法。如果验证失败,它就会抛出一个 ValidationError
异常,其中包含了错误信息和错误码,这些信息会在验证过程中展示给用户。
示例说明
这里我将给出两个示例,说明模型验证器的使用方法。
示例一:自定义邮箱格式验证器
在 Django 中内置了 EmailValidator
验证器,它可以验证一个字符串是否符合邮箱格式,但是有时候我们需要自定义更严格的邮箱格式验证器。
import re
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
def custom_email_validator(value):
if not re.match(r'[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}', value):
raise ValidationError(
_('请输入正确的邮箱地址。'),
code='invalid_email'
)
在上面的代码中,我们定义了一个 custom_email_validator
方法,它通过正则表达式验证一个字符串是否符合邮箱格式。如果验证失败,它就会抛出一个 ValidationError
异常,其中包含了错误信息和错误码。
现在,我们可以在模型的邮箱字段中加入我们自己的验证器。
from django.db import models
class Person(models.Model):
email = models.EmailField(validators=[custom_email_validator])
在这样的实现下,我们就可以自定义邮箱的格式校验规则并添加进模型的验证器列表中,以达到了自定义格式校验器的效果。
示例二:自定义身份证号码验证器
在进行用户身份验证、身份证关联操作等场景中,往往需要验证和标准化身份证号码。为了实现身份证号码的验证和标准化,我们可以自定义一个身份证号码验证器,并将其集成到 Django 模型的验证器中。
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
import re
def id_card_validator(value):
if not re.match(r'^[1-9][0-9]{5}(19|20)[0-9]{2}(0[1-9]|10|11|12)([0-2][1-9]|[1-3]0|31)[0-9]{3}([0-9]|[Xx])$', value):
raise ValidationError(
_('请输入正确的身份证号码。'),
code='invalid_id_card'
)
在上面的代码中,我们定义了一个 id_card_validator
方法,它通过正则表达式验证一个身份证号码是否符合规范。如果验证失败,它就会抛出一个 ValidationError
异常,其中包含了错误信息和错误码。
现在,我们可以在模型的身份证号码字段中加入我们自己的验证器。
from django.db import models
class Person(models.Model):
id_card_number = models.CharField(max_length=18, validators=[id_card_validator])
在这样的实现下,我们就可以自定义身份证号码的格式校验规则并添加进模型的验证器列表中,以达到自定义验证器的效果。
总结
本文介绍了 Django 模型验证器的用法和源码分析。通过使用模型验证器,我们可以很容易地实现自定义的数据验证逻辑,并避免在业务逻辑中进行大量的数据逻辑判断和错误处理。了解 Django 模型验证器的使用方法和实现逻辑,对于我们编写高质量的 Django 代码非常有帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Django模型验证器介绍与源码分析 - Python技术站