19. Flask web表單 Flask-WTF表單擴展

Web表單

web表單是web應(yīng)用程序的基本功能。

它是HTML頁面中負(fù)責(zé)數(shù)據(jù)采集的部件。表單有三個部分組成:表單標(biāo)簽、表單域、表單按鈕。表單允許用戶輸入數(shù)據(jù),負(fù)責(zé)HTML頁面數(shù)據(jù)采集,通過表單將用戶輸入的數(shù)據(jù)提交給服務(wù)器。

在Flask中,為了處理web表單,我們一般使用Flask-WTF擴展,它封裝了WTForms,并且它有驗證表單數(shù)據(jù)的功能。

安裝Flask-WTF擴展

pip3 install Flask-WTF

WTForms支持的HTML標(biāo)準(zhǔn)字段

字段對象 說明
StringField 文本字段
TextAreaField 多行文本字段
PasswordField 密碼文本字段
HiddenField 隱藏文本字段
DateField 文本字段,值為datetime.date格式
DateTimeField 文本字段,值為datetime.datetime格式
IntegerField 文本字段,值為整數(shù)
DecimalField 文本字段,值為decimal.Decimal
FloatField 文本字段,值為浮點數(shù)
BooleanField 復(fù)選框,值為True和False
RadioField 一組單選框
SelectField 下拉列表
SelectMultipleField 下拉列表,可選擇多個值
FileField 文本上傳字段
SubmitField 表單提交按鈕
FormField 把表單作為字段嵌入另一個表單
FieldList 一組指定類型的字段

WTForms常用驗證函數(shù)

驗證函數(shù) 說明
DataRequired 確保字段中有數(shù)據(jù)
EqualTo 比較兩個字段的值,常用于比較兩次密碼輸入
Length 驗證輸入的字符串長度
NumberRange 驗證輸入的值在數(shù)字范圍內(nèi)
URL 驗證URL
AnyOf 驗證輸入值在可選列表中
NoneOf 驗證輸入值不在可選列表中

使用Flask-WTF需要配置參數(shù)SECRET_KEY。

CSRF_ENABLED是為了CSRF(跨站請求偽造)保護。 SECRET_KEY用來生成加密令牌,當(dāng)CSRF激活的時候,該設(shè)置會根據(jù)設(shè)置的密匙生成加密令牌。

直接在HTML頁面寫form表單的示例

1. 在創(chuàng)建模板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.視圖函數(shù)中獲取表單數(shù)據(jù):

from flask import Flask,render_template,request

# 創(chuàng)建Flask的app應(yīng)用
app = Flask(__name__)

# index視圖函數(shù)
@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

訪問http://127.0.0.1:5000/login

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

直接使用HTML來寫表單可以實現(xiàn)提交信息的效果。但是需要考慮這幾點,如果參數(shù)很多,后臺也是需要一個個去校驗的,直接這樣去接受參數(shù)再校驗的話,這個工作量就會有些大。

而且還會出現(xiàn)csrf的攻擊問題,這時候就可以使用Flask-WTF來創(chuàng)建表單,避免這些問題。

使用Flask-WTF來編寫表單

1.編寫兩個視圖函數(shù),以及form表單類,用于注冊以及跳轉(zhuǎn)index頁面

from flask import Flask, render_template, redirect, url_for, session
# 導(dǎo)入Flask-WTF表單
from flask_wtf import FlaskForm
# 導(dǎo)入表單所需要的字段類型
from wtforms import StringField, PasswordField, SubmitField
# 導(dǎo)入表單的驗證器
from wtforms.validators import DataRequired, EqualTo

app = Flask(__name__)

# 設(shè)置密鑰,用于csrf_token的加解密
app.config["SECRET_KEY"] = "xhosd6f982yfhowefy29f"

# 定義表單的模型類
class RegisterForm(FlaskForm):
    """自定義的注冊表單模型類"""
    # DataRequired 保證數(shù)據(jù)必須填寫,并且不能為空
    user_name = StringField(label="用戶名", validators=[DataRequired("用戶名不能為空")]) #  參數(shù):名字,驗證器列表
    password = PasswordField(label="密碼", validators=[DataRequired("密碼不能為空")])
    password2 = PasswordField(label="確認(rèn)密碼",validators=[DataRequired("確認(rèn)密碼不能為空"),EqualTo("password", "兩次密碼不一致")])
    submit = SubmitField(label="提交")

@app.route("/register", methods=["GET", "POST"])
def register():
    # 創(chuàng)建表單對象, 如果是post請求,前端發(fā)送了數(shù)據(jù),flask會把數(shù)據(jù)在構(gòu)造form對象的時候,存放到對象中
    form = RegisterForm()

    # 判斷form中的數(shù)據(jù)是否合理
    # 如果form中的數(shù)據(jù)完全滿足所有的驗證器,則返回真,否則返回假
    if form.validate_on_submit():
        # 表示驗證合格
        # 提取數(shù)據(jù)
        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

如果不填寫任何數(shù)據(jù),則會提示如下:

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

正確填寫注冊信息,查看是否正常跳至index頁面,如下:

自動驗證表單內(nèi)容通過,并跳至index頁面。

從上面的示例可以看到,使用if form.validate_on_submit():就可以直接驗證所有字段,可以省事多了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容