20181006:為什麼要使用form表單而不是直接用html模板?校驗表單是怎樣處理的?
使用者登入流程:在forms.py中自己定義定義loginform類(其中包含登陸的表單,比如賬號、密碼、提交按鈕等)→ views.py中路由控制跳轉到登陸頁面模板(在其中傳入form),使用者輸入了賬號、密碼後點擊“提交”按鈕後,前端、後端校驗完成後,跳轉到登陸成功後的頁面。
為什麼不直接用寫好的html的登陸模板,而要通過loginform中轉一下?
顯然,如果使用者訪問登陸頁面,直接就 return render_template(“admin/login.html”)也沒問題,但是如果要在前端完成複雜一點的校驗(比如長度控制、要求只能英文賬號)就很困難,所以要引入forms.py,在裡面定義表單類class loginform,然後在return render_template的時候,引入這個loginform類return render_template(“admin/login.html”, form=form)。這樣,所有的前端校驗控制,就可以在這個類裡面來完成。
# 不使用form類的前端html模板如下:
<body>
<form method="get" action='/login'>
<label>使用者名稱:<input type="text" name="user" value=""></label><br>
<label>密碼:<input type="password" name="password" value=""></label><br>
< input type="submit" value="登入">
</form>
</body>
# 使用form類的前端html模板如下(僅列出了輸入使用者名稱的部分):
<div class="form-group has-feedback">
<!--這是原來的語句 <input name="user" type="text" class="form-control" placeholder="請輸入賬號!"> -->
{{ form.account }}
<span class="glyphicon glyphicon-envelope form-control-feedback" ></span>
<!-- 這是原來的語句 <div class="col-md-12" id="input_account"></div> -->
{% for err in form.account.errors %}
<div class="col-md-12">
<font style="color:red">{{ err }}</font>
</div>
{% endfor %}
</div>
前後端登陸資料的校驗在哪些地方、哪些過程中,怎樣完成校驗的?
登陸校驗是在4個部分中來進行的(4個部分可以同時有也可以部分有)。1-3 部分是在form.py中的class loginform類中完成,4部分是在views.py檢視模組中來完成。
- 網頁模板中欄位部分直接寫上required引數,實現輸入框不能為空的校驗。當網頁模板原始碼中嵌入了
required=“required”
引數,使用者如果讓輸入框為全空(即0個字元,連空格都沒有)則彈出“請填寫此欄位”或“必須填寫該欄位”提示(具體提示內容由瀏覽器控制而非我們的程式控制)。
<form action="demo_form.asp" method="get">
Name: <input type="text" name="usr_name" required="required" />
<input type="submit" />
</form>
- 直接定義欄位時的校驗,使用validators引數來控制。首先是直接定義欄位時的校驗,使用validators引數來控制。
- 在自定義驗證器 - namefield驗證器中來校驗。只要在class loginform中新增def validate_XXXX(self,field)函式(其中XXX為欄位物件,注意不是欄位名稱,而是欄位物件,如第1點中account就是一個StringField欄位物件)。
- 在views.py頁面檢視中的 轉發網址的路由裝飾器下的函式中校驗。一旦客戶點選了頁面中的“提交”按鈕,系統會先完成以上2步的校驗,檢驗通過後,才會到路由裝飾器函式來。這時可以在函式中校驗
if form.validate_on_submit()
的值,如果前面2步的校驗都正確,這個值就=TRUE,然後可以在if 中寫入需要校驗的程式碼。
從以上總結看出,輸入框校驗流程按以下順序優先順序處理:
- 網頁模板中:required引數 → 控制不能全空(有空格不算全空)
- 在 forms.py 模組,表單類(如class loginform)中:
輸入框的 validators 引數 → 控制不能全空格、長度、合法性簡單校驗
自定義驗證器validate_XXX → 進行程式控制複雜校驗(如:校驗賬號是否存在等) - 檢視模組中validate_on_submit() 中 → 也可以用程式控制複雜校驗
四個部分最終完成登入校驗。下面再就相關細節說明如下:
1、所有檢驗,都是在使用者點選了submit提交按鈕之後才會處理。
2、系統會第一步檢查,網頁模板中直接嵌入的:required引數。如果有嵌入這個引數,當輸入框為全空(即0個字元,空格也算字元),彈出“請填寫此欄位”或“必須填寫該欄位”提示(具體提示內容由瀏覽器控制而非我們的程式控制)。
3、在表單模組forms.py中表單類(如class loginform)中加入了引數 “validators=[DataRequired(‘賬號不能為空’)”,系統會自動在網頁模板中加入第2點中所說的"required”:"required引數,而不管原模板中是否有該引數。這樣,實際就這個引數實際也是校驗第一條。但是,這個引數可以設定為複雜校驗,如:
- DataRequired:控制“輸入框不能全為空格(注意區別全空)
- Length(1,32):校驗長度
- Regexp([A-Za-z0-9_.]*$’,0:校驗輸入是否合法。
錯誤資訊是如何顯示給使用者的?以上校驗錯誤中:
- 第1點的錯誤提示資訊是瀏覽器控制的,而非我們程式控制的。一般會彈出提示框在輸入框的下面。
- 第2點 ~ 第4點後的錯誤提示資訊,則由網頁模板中,程式碼所給的位置顯示到終端使用者網頁上。
<!--下面註釋掉的語句都是原始模板內容,保留是為了對比用 -->
<!-- <form action="" method="post" id="form-data"> -->
<form method="POST" id="form-data">
<div class="form-group has-feedback">
<!-- <input name="user" type="text" class="form-control" placeholder="請輸入賬號!"> -->
{{ form.account }} <!-- 引入loginform的account欄位的定義-->
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
<!-- <div class="col-md-12" id="input_account"></div> -->
<!-- 顯示錯誤資訊 -->
{% for err in form.account.errors %}
<div class="col-md-12">
<font style="color:red">{{ err }}</font>
</div>
{% endfor %}
</div>