form——验证器Validators

form表单最大的作用就是验证功能了,通过cleaned_data清洗,我们可以获取传来的值,通过参数、验证器、自定义验证方法,我们可以做到很多的验证。

验证器可用于在不同类型的字段之间重用验证逻辑。validators有自带的验证器,也可以自己定义一个验证器。在验证某个字段的时候,可以传递一个validators参数用来指定验证器,进一步对数据进行过滤。验证器有很多,但是很多验证器其实已经通过这个Field或者一些参数就可以指定了。比如EmailValidator,可以通过EmailField来指定,比如MaxValueValidator,可以通过max_value参数来指定。以下是一些常用的验证器:

from django.core import validators
  1. MaxValueValidator:验证最大值。
  2. MinValueValidator:验证最小值。
  3. MinLengthValidator:验证最小长度。
  4. MaxLengthValidator:验证最大长度。
  5. EmailValidator:验证是否是邮箱格式。
  6. URLValidator:验证是否是URL格式。
  7. RegexValidator:如果还需要更加复杂的验证,那么可以通过正则表达式的验证器

其中最常用到的就是RegexValidator,他可以通过正则自己定义验证器。如下面自己定义的一个验证手机号的例子。自定义验证器后,将验证器加入到validators的列表中。

# 创建手机号的正则校验器
mobile_validator = RegexValidator(r"^1[3-9]\d{9}$", "手机号码格式不正确")
 mobile = forms.CharField(max_length=11, min_length=11, validators=[mobile_validator, ],
                             error_messages={"min_length": "手机号长度有误", "max_length": "手机号长度有误",
                                             "required": "手机号不能为空"})

自定义验证

对于一些字段,可能还有一些更复杂的验证,我们可以采用函数的形式,构造自定义验证。一种是针对一个字段的验证,函数名为clean_字段名(self),还有一种是针对多个字段一起验证,函数名为clean(self),clean方法的第一步需要重新调用父类的clean方法。这两种方式,如果验证失败,那么就抛出一个验证错误ValidationError 。

# 验证手机号
        if (not real_image_code) or (image_text != real_image_code):
            raise forms.ValidationError("图片验证失败")
from django import forms

class ContactForm(forms.Form):
    # Everything as before.
    ...

    def clean_recipients(self):
        data = self.cleaned_data['recipients']
        if "fred@example.com" not in data:
            raise forms.ValidationError("You have forgotten about Fred!")

        # Always return a value to use as the new cleaned data, even if
        # this method didn't change it.
        return data
from django import forms

class RegisterTable(forms.Form):
    username = forms.CharField(min_length=1,max_length=10)
    phone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}", message="请输入正确的手机号码")])  # message会在表单类.errors.get_json_data()中获得

	# 对某个字段进行自定义的验证方式是,定义一个方法,这个方法的名字定义规则是:clean_fieldname
    def clean_phone(self):
        phone = self.cleaned_data.get("phone")  # 获得字段数据
        ret = User.objects.filter(phone=phone).exists()  # 如果已存在
        if ret:
            raise forms.ValidationError(message="{}已经被注册".format(phone))  # 抛出异常
            # message会在表单类.errors.get_json_data()中获得
        else:
        	return phone

下面是clean方法:

class RegisterTable(forms.Form):
    username = forms.CharField(min_length=1,max_length=10)
    phone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}", message="请输入正确的手机号码")])
    pwd = forms.CharField(min_length=5)  #密码
    pwd_repeat = forms.CharField(min_length=5)  #重复的密码

    def clean_phone(self):
        phone = self.cleaned_data.get("phone")  
        ret = User.objects.filter(phone=phone).exists()
        if ret:
            raise forms.ValidationError(message="{}已经被注册".format(phone))
        return phone

    def clean(self):  #最后审查
        ret = super(RegisterTable, self).clean()
        pwd = ret.get("pwd") # ==self.cleaned_data.get("pwd")
        pwd_repeat = ret.get("pwd_repeat")
        if pwd != pwd_repeat:
            raise forms.ValidationError(message="密码不一致")
        else:
            return ret

 

posted @ 2019-01-22 12:23  龙~白  阅读(4823)  评论(0编辑  收藏  举报