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())
<span class="token keyword">class</span> <span class="token class-name">Meta</span><span class="token punctuation">:</span>
model <span class="token operator">=</span> models<span class="token punctuation">.</span>User
fields <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'username'</span><span class="token punctuation">,</span> <span class="token string">'password'</span><span class="token punctuation">,</span> <span class="token string">'re_password'</span><span class="token punctuation">,</span> <span class="token string">'email'</span><span class="token punctuation">,</span> <span class="token string">'phone'</span><span class="token punctuation">,</span> <span class="token string">'code'</span><span class="token punctuation">]</span>
<span class="token keyword">def</span> <span class="token function">__init__</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span><span class="token punctuation">:</span>
<span class="token builtin">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>__init__<span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span>
<span class="token keyword">for</span> field <span class="token keyword">in</span> self<span class="token punctuation">.</span>fields<span class="token punctuation">.</span>values<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
field<span class="token punctuation">.</span>widget<span class="token punctuation">.</span>attrs<span class="token punctuation">[</span><span class="token string">'class'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'form-control'</span>
field<span class="token punctuation">.</span>widget<span class="token punctuation">.</span>attrs<span class="token punctuation">[</span><span class="token string">'placeholder'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'请输入{}'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>field<span class="token punctuation">.</span>label<span class="token punctuation">)</span>
# 验证用户名
def clean_username(self):
# 校验数据前,都需要获取到被校验的数据
username = self.cleaned_data['username']
<span class="token comment"># 开始校验:判断数据库中是否已存在用户名</span>
exists <span class="token operator">=</span> models<span class="token punctuation">.</span>User<span class="token punctuation">.</span>objects<span class="token punctuation">.</span><span class="token builtin">filter</span><span class="token punctuation">(</span>username<span class="token operator">=</span>username<span class="token punctuation">)</span><span class="token punctuation">.</span>exists<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> exists<span class="token punctuation">:</span>
<span class="token keyword">raise</span> ValidationError<span class="token punctuation">(</span><span class="token string">'用户名已存在'</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> username
<span class="token comment"># 验证邮箱</span>
<span class="token keyword">def</span> <span class="token function">clean_email</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>
email <span class="token operator">=</span> self<span class="token punctuation">.</span>cleaned_data<span class="token punctuation">[</span><span class="token string">'email'</span><span class="token punctuation">]</span>
exists <span class="token operator">=</span> models<span class="token punctuation">.</span>User<span class="token punctuation">.</span>objects<span class="token punctuation">.</span><span class="token builtin">filter</span><span class="token punctuation">(</span>email<span class="token operator">=</span>email<span class="token punctuation">)</span><span class="token punctuation">.</span>exists<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> exists<span class="token punctuation">:</span>
<span class="token keyword">raise</span> ValidationError<span class="token punctuation">(</span><span class="token string">'邮箱已存在'</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> email
<span class="token comment"># 加密密码</span>
<span class="token keyword">def</span> <span class="token function">clean_password</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>
pwd <span class="token operator">=</span> self<span class="token punctuation">.</span>cleaned_data<span class="token punctuation">[</span><span class="token string">'password'</span><span class="token punctuation">]</span>
<span class="token keyword">return</span> md5<span class="token punctuation">(</span>pwd<span class="token punctuation">)</span>
<span class="token comment"># 验证确认密码</span>
<span class="token keyword">def</span> <span class="token function">clean_re_password</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>
pwd <span class="token operator">=</span> self<span class="token punctuation">.</span>cleaned_data<span class="token punctuation">[</span><span class="token string">'password'</span><span class="token punctuation">]</span>
re_pwd <span class="token operator">=</span> md5<span class="token punctuation">(</span>self<span class="token punctuation">.</span>cleaned_data<span class="token punctuation">[</span><span class="token string">'re_password'</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> pwd <span class="token operator">!=</span> re_pwd<span class="token punctuation">:</span>
<span class="token keyword">raise</span> ValidationError<span class="token punctuation">(</span><span class="token string">'两次密码不一致'</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> re_pwd
<span class="token comment"># 验证手机号</span>
<span class="token keyword">def</span> <span class="token function">clean_phone</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>
phone <span class="token operator">=</span> self<span class="token punctuation">.</span>cleaned_data<span class="token punctuation">[</span><span class="token string">'phone'</span><span class="token punctuation">]</span>
exists <span class="token operator">=</span> models<span class="token punctuation">.</span>User<span class="token punctuation">.</span>objects<span class="token punctuation">.</span><span class="token builtin">filter</span><span class="token punctuation">(</span>phone<span class="token operator">=</span>phone<span class="token punctuation">)</span><span class="token punctuation">.</span>exists<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> exists<span class="token punctuation">:</span>
<span class="token keyword">raise</span> ValidationError<span class="token punctuation">(</span><span class="token string">'手机号已被注册'</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> phone
<span class="token comment"># 验证code</span>
<span class="token keyword">def</span> <span class="token function">clean_code</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>
code <span class="token operator">=</span> self<span class="token punctuation">.</span>cleaned_data<span class="token punctuation">[</span><span class="token string">'code'</span><span class="token punctuation">]</span>
phone <span class="token operator">=</span> self<span class="token punctuation">.</span>cleaned_data<span class="token punctuation">[</span><span class="token string">'phone'</span><span class="token punctuation">]</span>
<span class="token comment"># 连接redis</span>
conn <span class="token operator">=</span> get_redis_connection<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment"># 获取redis中存储的数据{'phone': 'code'}</span>
redis_code <span class="token operator">=</span> conn<span class="token punctuation">.</span>get<span class="token punctuation">(</span>phone<span class="token punctuation">)</span>
<span class="token keyword">if</span> <span class="token operator">not</span> redis_code<span class="token punctuation">:</span>
<span class="token keyword">raise</span> ValidationError<span class="token punctuation">(</span><span class="token string">'验证码失效或未发送,请重新发送'</span><span class="token punctuation">)</span>
redis_str_code <span class="token operator">=</span> redis_code<span class="token punctuation">.</span>decode<span class="token punctuation">(</span><span class="token string">'utf-8'</span><span class="token punctuation">)</span>
<span class="token comment"># 判断输入的code是否等于redis存储的code</span>
<span class="token keyword">if</span> code<span class="token punctuation">.</span>strip<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> redis_str_code<span class="token punctuation">:</span>
<span class="token keyword">raise</span> ValidationError<span class="token punctuation">(</span><span class="token string">'验证码错误,请重新输入'</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> code