<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
說到表單,在HTML中表單的建立時通過<form>
標籤實現的,在<form>
標籤內部,欄位通過使用<input>
標籤等定義。比如一個表單內部有使用者名稱,密碼框這些,都是通過<input>
,<label>
標籤等實現的。
一個簡單的表單:
<form> First name:<br> <input type="text" name="firstname"> <br> Last name:<br> <input type="text" name="lastname"> </form>
將表單提交給伺服器端處理時,伺服器端需要驗證表單中的欄位的取值是否符合要求。
在 Python 的 Web 開發中,表單內部的欄位標籤之類的,就不再使用HTML標籤來寫了,而是通過python類實現。
WTForms
在python中使用類定義表單,然後直接通過類定義生成對應的HTML程式碼,這種方式更加方便,而且使表單更易於重用。除非是非常簡單的程式,或者想讓表單的定義更加靈活,否則一般不會在模板中直接使用HTML程式碼寫表單。
WTForms 是一個靈活的表單驗證和表單渲染的庫,它的主要功能:
WTForms 可以與任意的 Web 框架和模板引擎一起使用。 在 Flask 框架或者 Django 框架中,都可以使用 WTForms。
Flask-WTF
在 WTForms 的基礎上提供了一些擴充套件,可以方便的在 Flask 框架中生成表單。
下面直接用程式碼講解如何建立表單。
首先,我們的目標是這樣一個頁面
一個簡單的登入頁面,讓使用者輸入使用者名稱,密碼,同時對使用者名稱和密碼進行驗證,驗證成功就輸出,驗證不成功需要重新輸入,並提示錯誤資訊。
首先,這是一個表單,表單內有一些文字,有文字方塊,有登入按鈕,這些都是通過python中的表單類建立的,使用的正是flask-wtf模組建立的。
先匯入需要的模組
#匯入表單類 from flask_wtf import FlaskForm #匯入欄位類 from wtforms import StringField,SubmitField,PasswordField #匯入驗證器類 from wtforms.validators import DataRequired,Length,Regexp
class LoginForm(FlaskForm): ''' 這些欄位物件會被渲染為html標籤 範例化一個文字欄位物件,設定引數 label:這個值可以拿出來放在標籤前面顯示 validators=[]驗證器列表,範例化的驗證器物件,裡面又可以設定引數 ''' #使用者名稱欄位 username = StringField( label='使用者名稱', validators=[ DataRequired(message='使用者名稱不能為空'), Length(3,20,message='使用者名稱長度在3-20個字元') ] ) password = PasswordField( label='密碼', validators=[ DataRequired(message='密碼不能為空'), Length(3,20,message='密碼長度在3-20個字元'), Regexp(r'^[a-z0-9A-Z]+$',message='密碼只能有字母,數位,下劃線組成') ] ) submit = SubmitField(label='登入')
我們建立了一個類LoginForm
,它是一個表單類,繼承了FlaskForm
,這個表單中包含一個使用者名稱username欄位,密碼password欄位,還有一個提交按鈕submit,這三個欄位作為了類LoginForm
的三個屬性。
我們發現使用者名稱,密碼這些實際是文字方塊,既然不用HTML程式碼實現,那麼怎麼實現呢?
使用的就是WTForms中的各種欄位類,比如這裡:
username = StringField()
StringField()
是WTForms 支援表單欄位類,它表示文字欄位,這樣一個欄位會被渲染為
<input id="username" name="username" type="text" value="">
注意:範例化物件的名稱是username ,被渲染後的input標籤中的id
和name
屬性值都叫username
WTForms 支援如下型別的表單欄位:
這只是一部分,還有很多其他支援的欄位。
接著看程式碼:
username = StringField( label='使用者名稱', validators=[ DataRequired(message='使用者名稱不能為空'), Length(3,20,message='使用者名稱長度在3-20個字元') ] )
StringField類需要傳遞一些引數:
label='使用者名稱'
,這個引數可以直接在模板頁面中顯示,使用form.username.label
,把它放在文字方塊的前面,像下面這樣:
validators=[ ]
這個參數列示對這個欄位使用的驗證器列表。驗證器就是對這個欄位使用那些驗證,比如這裡DataRequired,Length
兩個驗證器類,同樣驗證器類需要範例化然後傳入引數。比如:
Length(3,20,message='使用者名稱長度在3-20個字元')
限定長度在3-20字元,如果驗證不通過,就彈出錯誤資訊:message='使用者名稱長度在6-20個字元'
。
驗證器也有很多型別,常見的驗證器類有:
還可以自定義驗證器類等等。
我們建立了一個單獨的檔案loginform.py
from flask_wtf import FlaskForm from wtforms import StringField,PasswordField,SubmitField from wtforms.validators import DataRequired,Regexp,Length class LoginForm(FlaskForm): #<input id="username1" maxlength="20" minlength="3" name="username1" required type="text" value=""> username = StringField( label='使用者名稱', validators=[ DataRequired(message='使用者名稱不能為空'), Length(3,20,message='使用者名稱長度在3-20個字元') ] ) password = PasswordField( label='密碼', validators=[ DataRequired(message='密碼不能為空'), Length(3,20,message='密碼長度在3-20個字元'), Regexp(r'^[a-z0-9A-Z]+$',message='密碼只能有字母,數位,下劃線組成') ] ) submit = SubmitField(label='登入')
表單類建立好之後,可以做一個簡單的測試:
把這個表單顯示出來
首先,我們在app.py檔案中:
from flask import Flask,render_template,request from loginform import LoginForm app = Flask(__name__) app.config['SECRET_KEY'] = 'hard to guess string' @app.route('/',methods=['GET','POST']) def login(): loginform = LoginForm() if request.method == 'GET': return render_template('login.html',form = loginform) return 'hello' if __name__ == '__main__': app.run()
app.config['SECRET_KEY'] = 'hard to guess string'
用於防範 CSRF 攻擊,具體的我也不清楚,就不再細說了,總之需要設定
接著,在根路由下/
,有檢視函數login
,存取這個路由的方法可以是GET,或者POST。首先假設是GET,我們就需要把之前的表單渲染出來,具體的做法就是:
使用建立的表單類LoginForm
範例化一個表單物件loginform ,如果請求方法是GET,就去渲染login.html
,然後表單物件作為引數傳遞過去。所以我們還需要設計一下login.html
檔案。
login.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登入頁面</title> </head> <body> <form action="{{ url_for('login') }}" method="post"> <table> <tbody> <tr> <td>{{ form.username.label }}</td> <td>{{ form.username }}</td> <td>{% for err in form.username.errors %} {{ err }} {% endfor %} </td> <td>{{ form.test }}</td> </tr> <tr> <td>{{ form.password.label }}</td> <td>{{ form.password }}</td> <td>{% for err in form.password.errors %} {{ err }} {% endfor %} </td> </tr> <tr> <td>{{ form.submit }}</td> </tr> {{ form.hidden_tag() }} </tbody> </table> </form> </body> </html>
這裡使用了一個表格佈局,然後表單的action="{{ url_for('login') }}" method="post"
,設定了表單的提交路徑,以及提交方法。
<td>{{ form.username.label }}</td>#拿到username的label值顯示出來 <td>{{ form.username }}</td>#顯示username這個欄位 <td>{% for err in form.username.errors %}#這是錯誤資訊,如果驗證不通過會顯示錯誤資訊 {{ err }} {% endfor %} </td>
最後,還要注意到: {{ form.hidden_tag() }}
, 用於防範 CSRF 攻擊,生成 <input id=“csrf_token”/>
標籤。總之必須要加上,不加上,後面驗證資料的時候會出問題。
接著,執行app.py,存取根路徑/
,則是GET方法存取,會渲染出login.htm
l檔案。
接著,我們需要實現,使用者輸入資料,我們進行驗證,驗證不成功就提示錯誤資訊,驗證成功就登入成功。
回到表單類中,我們可以發現使用的驗證器有這幾種:
其中,DataRequired,Length直接被渲染為HTML中input標籤的屬性:
maxlength="" minlength="" required
這時候驗證就是在瀏覽器上完成的了,而不是在伺服器。使用者端方式可以實時動態的提示使用者輸入是否正確,只有使用者輸入正確後才會將表單資料傳送給伺服器。使用者端驗證可以增強使用者體驗,降低伺服器負載。
參考書上說,Flask程式中使用WTForms實現的就是伺服器驗證,但是有些欄位又會被渲染為HTML5的屬性,所以也不全是伺服器驗證。
這就是瀏覽器給出的驗證提示
但是正則驗證器,確實是在伺服器端完成驗證的
Regexp(r'^[a-z0-9A-Z]+$',message='密碼只能有字母,數位,下劃線組成')
那麼怎麼在伺服器驗證資料呢,首先,我們的資料會提交到/
路徑,使用的是POST方法。
表單類物件loginform,有一個驗證方法,loginform.validate()
,呼叫這個方法時,會去呼叫你每一個欄位中使用的每一個驗證器去驗證資料,全部驗證通過返回True,失敗返回False。
@app.route('/',methods=['GET','POST']) def login(): loginform = LoginForm() if request.method == 'GET': return render_template('login.html',form = loginform) elif request.method == 'POST' and loginform.validate(): return f'使用者 {loginform.username.data}登入成功' else: return render_template('login.html',form = loginform)
loginform.validate()==True
,表示驗證通過,這時候我們返回登入成功,同時使用loginform.username.data
可以拿到使用者輸入的使用者名稱。validate()
方法,返回False,產生了錯誤資訊,錯誤資訊在form.username.errors
,是一個列表,這時候login.html中的錯誤資訊列表就是有輸出了。測試一下:我的密碼欄位設定了正則驗證,只允許輸入字母數位下劃線,而且字元個數在3-20個。
首先,不填寫欄位,瀏覽器端會自動驗證
輸入正確格式的密碼:
輸入錯誤格式的密碼:
到此這篇關於Flask表單與表單驗證實現流程介紹的文章就介紹到這了,更多相關Flask表單內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45