Django - 自定义Form校验规则

自定义Form校验规则

class MyForm(forms.Form):
    # form可以校验的规则
    username = fields.CharField(max_length=32,min_length=3)  
    password = fields.CharField(max_length=32,min_length=3)
    re_password = fields.CharField(max_length=32,min_length=3)   

局部钩子 - 校验用户名不能重复

def clean_username(self):
    # 获取username
    username = self.cleaned_data['username']

    # 判断用户名是否存在
    if models.User.objects.filter(username=username).count():
        # 存在即不符合规则,必须抛出ValidationError异常
        raise ValidationError('该用户名已存在')
    # 校验通过,则返回清洗后的数据
    return self.cleaned_data['username']

全局钩子 - 检验两次密码输入一致

def clean(self):
    # 获取两次输入的密码
    password = self.cleaned_data['password']
    re_password = self.cleaned_data['re_password']
    
    # 判断是否相等,相等则返回数据,否则抛出ValidationError异常
    if password == re_password:
        return self.cleaned_data
    else:
        raise ValidationError('两次密码输入不一致')  # 错误信息放在“__all__”里
from django import forms
from django.forms import widgets

from django.core.exceptions import ValidationError

from app01 import models


# 写一个类,继承Form  没有头像校验的字段
class RegForm(forms.Form):
    username = forms.CharField(max_length=18, min_length=3, label="用户名",
                               error_messages={'max_length': '太长了',
                                               'min_length': '太短了',
                                               'required': '不能为空'},
                               widget=widgets.TextInput(attrs={'class': 'form-control'}),
                               )
    password = forms.CharField(max_length=18, min_length=3, label="密码",
                               error_messages={'max_length': '太长了',
                                               'min_length': '太短了',
                                               'required': '不能为空'},
                               widget=widgets.PasswordInput(attrs={'class': 'form-control'}),
                               )
    re_pwd = forms.CharField(max_length=18, min_length=3, label="确认密码",
                             error_messages={'max_length': '太长了',
                                             'min_length': '太短了',
                                             'required': '不能为空'},
                             widget=widgets.PasswordInput(attrs={'class': 'form-control'}),
                             )
    email = forms.EmailField(max_length=18, min_length=3, label="邮箱",
                             error_messages={'max_length': '太长了',
                                             'min_length': '太短了',
                                             'required': '不能为空'},
                             widget=widgets.EmailInput(attrs={'class': 'form-control'}),
                             )

    # 局部钩子,局部校验
    def clean_username(self):
        # 取出name对应的值
        name = self.cleaned_data.get('username')
        # if name.startswith('sb'):
        #     #校验不通过,抛异常
        #     raise ValidationError('不能以sb开头')
        #     #校验通过,直接return name值
        # else:
        #     return name
        user = models.UserInfo.objects.filter(username=name).first()
        if user:
            # 用户存在,抛异常
            raise ValidationError('用户已经存在')
        else:
            return name

    # 全局钩子,全局校验

    def clean(self):
        pwd = self.cleaned_data.get('password')
        r_pwd = self.cleaned_data.get('re_pwd')
        if pwd == r_pwd:
            # 校验通过,返回清洗后的数据
            return self.cleaned_data
        else:
            # 校验不通过,抛异常
            raise ValidationError('两次密码不一致')


注意:全局钩子与局部钩子的函数名、判断异常和返回值都是根据内部源码写的
1. 函数名为“clean_字段名”或者“clean”
2. 数据校验有误,只能抛ValidationError异常,因为在源码中捕获ValidationError异常
3. 数据校验成功,返回数据

posted @ 2019-09-22 00:40  『侠客行』  阅读(364)  评论(0编辑  收藏  举报