當咱們好比在註冊頁面的時候,獲取用戶輸入的用戶名、密碼或郵箱是否符合咱們設置的規則,好比設置密碼長度,當不足的時候會提示信息html
前端
def register(request): # 定義錯誤信息空字典 error_dict = {'username': '', 'password': ''} if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') if '666' in username: error_dict['username'] = '光喊666是不行的!!!' if not password: error_dict['password'] = '密碼不能爲空!!!' return render(request, 'register.html', locals())
前端代碼:django
<form action="" method="post"> <p>用戶名: <input type="text" name="username"> <span style="color: red">{{ error_dict.username }}</span> </p> <p>密碼: <input type="text" name="password"> <span style="color: red">{{ error_dict.password }}</span> </p> <input type="submit"> </form>
以上咱們作了:後端
一、手寫獲取用戶輸入的前端頁面代碼 >>> 渲染頁面瀏覽器
二、後端獲取用戶數據並作合法校驗 >>> 校驗數據ide
三、將校驗以後的結果渲染到前端頁面 >>> 展現信息函數
咱們能夠經過forms組件來幫咱們作這些事post
總結一下,其實form組件的主要功能以下:測試
from django import forms class MyForms(forms.Form): # 用戶名最大8位,最少2位,錯誤提示信息,容許爲空,默認值 username = forms.CharField(max_length=8, min_length=2, error_messages={ 'max_length': '用戶名最長8位', 'min_length': '用戶名最短2位', }, required=False, initial='shen') # 密碼必須最少3位最多8位,且標籤名是密碼,控制type屬性爲password password = forms.CharField(max_length=8, min_length=3, label='密碼:', widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})) # 必須郵箱格式 email = forms.EmailField(error_messages={ 'required': '郵箱必填', 'invalid': '郵箱格式不正確' }) # 引用模塊validators中RexValidator進行正則校驗 phone = forms.CharField( validators=[ RegexValidator(r'^[0-9]+$', '請輸入數字') ] )
label input的提示信息 error_messages 自定義報錯的提示信息 required 設置字段是否容許爲空,容許爲空改成False initial 設置默認值 widget 控制type類型及屬性 widget=forms.widgets.TextInput(attrs={'class':'form-control c1 c2'}) widget=forms.widgets.PasswordInput(attrs={'class':'form-control'}) validators 正則校驗 validators=[ RegexValidator(r'^[0-9]+$', '請輸入數字') ]
# 單選 gender = forms.ChoiceField( choices=((1, "男"), (2, "女"), (3, "保密")), label="性別", initial=3, widget=forms.widgets.RadioSelect() ) # 單選下拉框 hobby = forms.ChoiceField( choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),), label="愛好", initial=3, widget=forms.widgets.Select() ) # 多選 hobby1 = forms.MultipleChoiceField( choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),), label="愛好", initial=[1, 3], widget=forms.widgets.SelectMultiple() ) # 單選 keep = forms.ChoiceField( label="是否記住密碼", initial="checked", widget=forms.widgets.CheckboxInput() ) # 多選 hobby2 = forms.MultipleChoiceField( choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),), label="愛好", initial=[1, 3], widget=forms.widgets.CheckboxSelectMultiple() )
def reg(request): # 先生成一個空的類的對象 form_obj = MyForms() if request.method == 'POST': # 獲取用戶數據並交給forms組件校驗 request.POST # 此處form_obj與上面定義的空對象要相同 form_obj = MyForms(request.POST) # 獲取校驗結果 if form_obj.is_valid(): return HttpResponse('數據沒問題') else: # 獲取校驗失敗的字段和提示信息 print(form_obj.errors) # 直接將該對象傳給前端頁面 return render(request, 'reg.html', locals())
一、將數據字典傳入咱們寫的類中ui
form_obj = MyForms({'username':'shen', 'password': '11', 'email': '111', 'phone': '1234'})
二、判斷數據是否符合校驗規則
form_obj.is_valid() # 該方法獲得結果只有True和False,只有所有經過校驗纔會返回True
三、獲取哪些數據是校驗經過的
form_obj.cleaned_data
四、獲取哪些數據是校驗失敗的,和失敗緣由
form_obj.errors
五、注意:forms組件全部的字段都必需要傳參,不能少了,可是傳多了沒事,多傳的會自動忽略
form_obj = views.MyRegForm({'username':'jason','password':'123456','phone':'11213'}) form_obj.is_valid() # False form_obj.errors # {'email': ['This field is required.']} form_obj=views.MyRegForm({'username':'jason','password':'123456',"email":'123@qq.com',"hobby":'hahahaha'}) form_obj.is_valid() # True form_obj.cleaned_data # {'username': 'jason', 'password': '123456', 'email': '123@qq.com'} form_obj.errors # {}
校驗數據先後端都應該要有的,可是前端的校驗弱不由風容易被修改,因此後端的校驗必需要很是全面
如何取消前端瀏覽器幫咱們作的自動校驗功能:利用form表單中的 novalidate
<form action="" method="post" novalidate>
form組件會幫你在前端渲染用戶的輸入(選擇,輸入,下拉,文件)的標籤,不會渲染按鈕,而且渲染出的默認提示信息都是類中的字段首字母大寫
三種渲染方式:
{#第一種渲染方式 本地測試方便,封裝程度很高,擴展性低#} <form action="" method="post"> {{ form_obj.as_p }} 每個input框都是p標籤 {{ form_obj.as_table }} 按照表格渲染一行展現 {{ form_obj.as_ul }} 按照無序列表渲染展現 <input type="submit"> </form>
{#第二種渲染方式 擴展性高,可是書寫太繁瑣#} <form action="" method="post"> {# 給username添加label標籤和id#} <label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label> {{ form_obj.username }} {# 獲取標籤的展現信息 獲取標籤input框#} {{ form_obj.password.label }} {{ form_obj.password }} {{ form_obj.email.label }}: {{ form_obj.email }} {{ form_obj.phone.label }}: {{ form_obj.phone }} <input type="submit"> </form>
{#第三種渲染方式 推薦使用#} <form action="" method="post" novalidate> {# 循環取出沒一個字段#} {% for form in form_obj %} <p> {# 字段展現提示信息 字段input框#} {{ form.label }} {{ form }} {# 渲染錯誤提示信息#} <span>{{ form.errors.0 }}</span> </p> {% endfor %} <input type="submit"> </form>
實現自定義的校驗功能,在自定義類下使用鉤子函數
在form類中使用 clean() 方法,實現同時對多個字段進行操做
# 定義全局鉤子來校驗兩次密碼是否相同 # 定義全局鉤子,必須是clean def clean(self): # 獲取字段對應的數據 password = self.cleaned_data.get('password') repassword = self.cleaned_data.get('repassword') if not password == repassword: # 添加錯誤提示到repassword字段中的錯誤信息中 self.add_error('repassword', '兩次密碼不同!!!') # 返回拿到的全局數據 return self.cleaned_data
在form類中使用 clean_字段名() 方法,實現對某一個字段的校驗
# 定義局部鉤子校驗用戶名中不能有GG def clean_username(self): # 獲取局部定義鉤子操做的字段數據 username = self.cleaned_data.get('username') if 'GG' in username: # 添加錯誤信息到username錯誤信息中 self.add_error('username', 'GG是不行的') # 返回拿到的局部鉤子字段 return username
總結:若是想同時操做多個字段的數據就用全局鉤子,若是想操做單個字段的數據,就用局部鉤子