ModelForm中使用钩子函数校验数据
class RegisterForm(forms.ModelForm):
password = forms.CharField(label='密码', widget=forms.PasswordInput(), min_length=6, max_length=32, error_messages={'min_length': '密码长度不能小于6个字符', 'max_length': '密码长度不能大于32个字符'})
re_password = forms.CharField(label='确认密码', widget=forms.PasswordInput(), min_length=6, max_length=32, error_messages={'min_length': '密码长度不能小于6个字符', 'max_length': '密码长度不能大于32个字符'})
phone = forms.CharField(label='手机号', validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机号格式错误')])
code = forms.CharField(label='验证码', widget=forms.TextInput())
class Meta:
model = models.User
fields = ['username', 'password', 're_password', 'email', 'phone', 'code']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields.values():
field.widget.attrs['class'] = 'form-control'
field.widget.attrs['placeholder'] = '请输入{}'.format(field.label)
# 验证用户名
def clean_username(self):
# 校验数据前,都需要获取到被校验的数据
username = self.cleaned_data['username']
# 开始校验:判断数据库中是否已存在用户名
exists = models.User.objects.filter(username=username).exists()
if exists:
raise ValidationError('用户名已存在')
return username
# 验证邮箱
def clean_email(self):
email = self.cleaned_data['email']
exists = models.User.objects.filter(email=email).exists()
if exists:
raise ValidationError('邮箱已存在')
return email
# 加密密码
def clean_password(self):
pwd = self.cleaned_data['password']
return md5(pwd)
# 验证确认密码
def clean_re_password(self):
pwd = self.cleaned_data['password']
re_pwd = md5(self.cleaned_data['re_password'])
if pwd != re_pwd:
raise ValidationError('两次密码不一致')
return re_pwd
# 验证手机号
def clean_phone(self):
phone = self.cleaned_data['phone']
exists = models.User.objects.filter(phone=phone).exists()
if exists:
raise ValidationError('手机号已被注册')
return phone
# 验证code
def clean_code(self):
code = self.cleaned_data['code']
phone = self.cleaned_data['phone']
# 连接redis
conn = get_redis_connection()
# 获取redis中存储的数据{'phone': 'code'}
redis_code = conn.get(phone)
if not redis_code:
raise ValidationError('验证码失效或未发送,请重新发送')
redis_str_code = redis_code.decode('utf-8')
# 判断输入的code是否等于redis存储的code
if code.strip() != redis_str_code:
raise ValidationError('验证码错误,请重新输入')
return code