實現目標:用戶名不能重複、密碼不能是純數字html
class UserInfo(models.Model): name=models.CharField(max_length=32) pwd=models.CharField(max_length=32) email=models.CharField(max_length=32)
from django import forms from app01.models import UserInfo from django.core.exceptions import NON_FIELD_ERRORS, ValidationError #錯誤管理 from django.forms import widgets #widgets魔法工具包 class UserForm(forms.Form): #建立校驗規則類。,必須繼承forms組件類 name=forms.CharField(min_length=5,label="用戶名") pwd=forms.CharField(label="密碼") email=forms.EmailField(label="郵箱") # 自定義鉤子(匹配規則) # 用戶名不能重複 def clean_name(self): val=self.cleaned_data.get('name') #先取值 ret=UserInfo.objects.filter(name=val) #查看數據庫中是否有這個值 if not ret: #若是在數據庫中沒有,就經過匹配 return val else:#不然,說明在數據庫中有該用戶名 raise ValidationError("用戶名已存在") # 密碼不能是純數字 def clean_pwd(self): val = self.cleaned_data.get('pwd') # 先取值 print(type(val)) if val.isdigit(): #判斷是不是數字 raise ValidationError("密碼不能是純數字") else: return val
def reg(request): if request.method=='POST': form=UserForm(request.POST) #把數據放在規則類裏校驗 if form.is_valid():#校驗數據 UserInfo.objects.create(**form.cleaned_data) #符合規則後咱們把數據插入到數據庫中,由於數據是字典,因此須要打散 else: error=form.errors return render(request,'reg.html',locals()) #把錯誤數據渲染到模板 else: form=UserForm() #沒有把咱們輸入的數據放進去查看是否匹配規則。咱們的目的是把UserForm規則類的字段渲染到頁面 return render(request,'reg.html',locals())
<form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} <div> <label for="">{{ field.label }}</label> {# 顯示字段名:#} {{ field }}{# 顯示input框:#} <span class="error">{{ field.errors }}</span> {# 顯示錯誤信息:#} </div> {% endfor %} <input type="submit"> </form>
須要 確認密碼 和 密碼 進行比對。前端
class UserInfo(models.Model): name=models.CharField(max_length=32) pwd=models.CharField(max_length=32) r_pwd=models.CharField(max_length=32) email=models.CharField(max_length=32)
from django import forms from app01.models import UserInfo from django.core.exceptions import NON_FIELD_ERRORS, ValidationError #錯誤管理 from django.forms import widgets #widgets魔法工具包 class UserForm(forms.Form): name=forms.CharField(min_length=5,label="用戶名") pwd=forms.CharField(label="密碼") r_pwd=forms.CharField(label="確認密碼") email=forms.EmailField(label="郵箱") # 自定義局部鉤子 # 用戶名不能重複 def clean_name(self): val=self.cleaned_data.get('name') ret=UserInfo.objects.filter(name=val) if not ret: return val else: raise ValidationError("用戶名已存在") # 密碼不能是純數字 def clean_pwd(self): val = self.cleaned_data.get('pwd') print(type(val)) if val.isdigit(): raise ValidationError("密碼不能是純數字") else: return val def clean(self):#全局鉤子 pwd=self.cleaned_data.get("pwd") #有可能第一層校驗未經過取值是空 r_pwd=self.cleaned_data.get("r_pwd") print("=======>") if pwd and r_pwd: #若是兩個都經過了第一層說明clean_data中有值就是true if pwd==r_pwd: print(1111) return self.cleaned_data else: print(222222) raise ValidationError("兩次密碼不一致") else: #若是兩個不在clean_data裏,那就不必在比較了,由於自己就已經在errors裏了 return self.cleaned_data
視圖函數git
def reg(request): if request.method=='POST': form=UserForm(request.POST) if form.is_valid():#校驗數據 UserInfo.objects.create(**form.cleaned_data) else: error=form.errors if form.errors.get("__all__"):#第二層全局錯誤,__all__:全局錯誤信息 g_error=form.errors.get("__all__")[0] return render(request,'reg.html',locals()) #把錯誤數據渲染到模板 else: form=UserForm() return render(request,'reg.html',locals())
<form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} <div> <label for="">{{ field.label }}</label> {# 顯示字段名:#} {{ field }}{# 顯示input框:#} <span class="error">{{ field.errors }}</span> {# 顯示錯誤信息:#} {% if field.label == "確認密碼" %} <span>{{ g_error|default:"" }}</span> {% endif %} </div> {% endfor %} <input type="submit"> </form>
從上面的案例中咱們知道了如何自定義一個鉤子函數,那麼爲何是那樣寫的呢?數據庫
這一切都在源碼中有定義------>參看源碼分析:博文 Django-源碼-Forms組件--自定義規則(鉤子)django