Flask web表單 Flask-WTF表單擴展
- 2019 年 12 月 19 日
- 筆記
Web表單
web表單是web應用程式的基本功能。
它是HTML頁面中負責數據採集的部件。表單有三個部分組成:表單標籤、表單域、表單按鈕。表單允許用戶輸入數據,負責HTML頁面數據採集,通過表單將用戶輸入的數據提交給伺服器。
在Flask中,為了處理web表單,我們一般使用Flask-WTF擴展,它封裝了WTForms,並且它有驗證表單數據的功能。
安裝Flask-WTF擴展
pip3 install Flask-WTF
WTForms支援的HTML標準欄位
欄位對象 |
說明 |
---|---|
StringField |
文本欄位 |
TextAreaField |
多行文本欄位 |
PasswordField |
密碼文本欄位 |
HiddenField |
隱藏文本欄位 |
DateField |
文本欄位,值為datetime.date格式 |
DateTimeField |
文本欄位,值為datetime.datetime格式 |
IntegerField |
文本欄位,值為整數 |
DecimalField |
文本欄位,值為decimal.Decimal |
FloatField |
文本欄位,值為浮點數 |
BooleanField |
複選框,值為True和False |
RadioField |
一組單選框 |
SelectField |
下拉列表 |
SelectMultipleField |
下拉列表,可選擇多個值 |
FileField |
文本上傳欄位 |
SubmitField |
表單提交按鈕 |
FormField |
把表單作為欄位嵌入另一個表單 |
FieldList |
一組指定類型的欄位 |
WTForms常用驗證函數
驗證函數 |
說明 |
---|---|
DataRequired |
確保欄位中有數據 |
EqualTo |
比較兩個欄位的值,常用於比較兩次密碼輸入 |
Length |
驗證輸入的字元串長度 |
NumberRange |
驗證輸入的值在數字範圍內 |
URL |
驗證URL |
AnyOf |
驗證輸入值在可選列表中 |
NoneOf |
驗證輸入值不在可選列表中 |
使用Flask-WTF需要配置參數SECRET_KEY。
CSRF_ENABLED是為了CSRF(跨站請求偽造)保護。 SECRET_KEY用來生成加密令牌,當CSRF激活的時候,該設置會根據設置的密匙生成加密令牌。
直接在HTML頁面寫form表單的示例
1. 在創建模板login.html頁面中直接寫form表單:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="post"> <input type="text" name="username" placeholder='Username'> <input type="password" name="password" placeholder='password'> <input type="submit"> </form> {% if method == 'GET' %} 請求的方式:{{ method }} {% elif method == 'POST' %} 請求的方式:{{ method }} 用戶名:{{ username }} 密碼: {{ password }} {% endif %} </body> </html>
2.視圖函數中獲取表單數據:
from flask import Flask,render_template,request # 創建Flask的app應用 app = Flask(__name__) # index視圖函數 @app.route("/login",methods=['GET','POST']) def login(): context = dict() if request.method == 'POST': username = request.form['username'] password = request.form['password'] print(username, password) context = { 'username': username, 'password': password, } context.update({'method': request.method}) return render_template('login.html', **context) if __name__ == '__main__': app.run(debug=True)
3.測試login

再次輸入用戶名和密碼直接提交如下:


直接使用HTML來寫表單可以實現提交資訊的效果。但是需要考慮這幾點,如果參數很多,後台也是需要一個個去校驗的,直接這樣去接受參數再校驗的話,這個工作量就會有些大。
而且還會出現csrf的攻擊問題,這時候就可以使用Flask-WTF來創建表單,避免這些問題。
使用Flask-WTF來編寫表單
1.編寫兩個視圖函數,以及form表單類,用於註冊以及跳轉index頁面
from flask import Flask, render_template, redirect, url_for, session # 導入Flask-WTF表單 from flask_wtf import FlaskForm # 導入表單所需要的欄位類型 from wtforms import StringField, PasswordField, SubmitField # 導入表單的驗證器 from wtforms.validators import DataRequired, EqualTo app = Flask(__name__) # 設置密鑰,用於csrf_token的加解密 app.config["SECRET_KEY"] = "xhosd6f982yfhowefy29f" # 定義表單的模型類 class RegisterForm(FlaskForm): """自定義的註冊表單模型類""" # DataRequired 保證數據必須填寫,並且不能為空 user_name = StringField(label="用戶名", validators=[DataRequired("用戶名不能為空")]) # 參數:名字,驗證器列表 password = PasswordField(label="密碼", validators=[DataRequired("密碼不能為空")]) password2 = PasswordField(label="確認密碼",validators=[DataRequired("確認密碼不能為空"),EqualTo("password", "兩次密碼不一致")]) submit = SubmitField(label="提交") @app.route("/register", methods=["GET", "POST"]) def register(): # 創建表單對象, 如果是post請求,前端發送了數據,flask會把數據在構造form對象的時候,存放到對象中 form = RegisterForm() # 判斷form中的數據是否合理 # 如果form中的數據完全滿足所有的驗證器,則返回真,否則返回假 if form.validate_on_submit(): # 表示驗證合格 # 提取數據 uname = form.user_name.data pwd = form.password.data pwd2 = form.password2.data print(uname, pwd, pwd2) session["user_name"] = uname return redirect(url_for("index")) return render_template("register.html", form=form) @app.route("/index") def index(): user_name = session.get("user_name", "") return "hello %s" % user_name if __name__ == '__main__': app.run(debug=True)
2.編寫一個register.html模板,用於作為註冊頁面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="post"> {{ form.csrf_token }} {{ form.user_name.label }} <p>{{form.user_name}}</p> {% for msg in form.user_name.errors %} <p>{{msg}}</p> {% endfor %} {{ form.password.label }} <p>{{form.password}}</p> {% for msg in form.password.errors %} <p>{{msg}}</p> {% endfor %} {{ form.password2.label }} <p>{{form.password2}}</p> {% for msg in form.password2.errors %} <p>{{msg}}</p> {% endfor %} {{form.submit}} </form> </body> </html>
3.登錄註冊頁面
訪問http://127.0.0.1:5000/register
如果不填寫任何數據,則會提示如下:

填寫兩次密碼不一致,提示如下:


正確填寫註冊資訊,查看是否正常跳至index頁面,如下:

自動驗證表單內容通過,並跳至index頁面。
從上面的示例可以看到,使用if form.validate_on_submit():就可以直接驗證所有欄位,可以省事多了。