第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Flask 的表單驗(yàn)證器

在 Web 頁面中,表單是一種常見的元素,表單包含有多個(gè)字段,通常字段的取值需要在一定的范圍內(nèi),例如:QQ 注冊(cè)時(shí),名稱不可以為空,密碼的長度至少是 8 個(gè)字符,如下圖所示:

將表單提交給服務(wù)端處理時(shí),服務(wù)端需要驗(yàn)證表單中的字段的取值是否符合要求。本節(jié)學(xué)習(xí) Flask 中提供表單驗(yàn)證的功能,學(xué)習(xí)如何對(duì)表單中的字段的取值進(jìn)行有效性檢查。

1. 表單驗(yàn)證器

1.1 WTForms 和 Flask-WTF

在 Python 的 Web 開發(fā)中,WTForms 是一個(gè)靈活的表單驗(yàn)證和表單渲染的庫,它的主要功能:

  • 驗(yàn)證表單中的字段的取值是否符合要求;
  • 渲染輸出表單的 HTML 代碼。

WTForms 可以與任意的 Web 框架和模板引擎一起使用。 在 Flask 框架或者 Django 框架中,都可以使用 WTForms。

Flask-WTF 在 WTForms 的基礎(chǔ)上提供了一些擴(kuò)展,可以方便的在 Flask 框架中生成表單。

1.2 表單字段

WTForms 支持如下類型的表單字段:

字段類型 說明
StringField 文本字段
TextAreaField 多行文本字段
PasswordField 密碼文本字段
HiddenField 隱藏文本字段
DateField 文本字段,值為datetime.date格式
IntegerField 文本字段,值為整數(shù)
DecimalField 文本字段, 值為decimal.Decimal
FloatField 文本字段,值為浮點(diǎn)數(shù)
BooleanField 復(fù)選框, 值為True 和 False
RadioField 一組單選框
SelectField 下拉列表
FileField 文件上傳字段
SubmitField 表單提交按鈕

1.3 驗(yàn)證器

WTForms 支持如下類型的表單驗(yàn)證:

驗(yàn)證類型 說明
Email 驗(yàn)證電子郵件地址
EqualTo 比較兩個(gè)字段的值;常用于要求輸入兩次秘鑰進(jìn)行確認(rèn)的情況
Length 驗(yàn)證輸入字符串的長度
NumberRange 驗(yàn)證輸入的值在數(shù)字范圍內(nèi)
DateRequired 確保字段中有數(shù)據(jù)

2. 程序功能和結(jié)構(gòu)

2.1 程序功能

在下面的小節(jié),我們將使用 WTForms 實(shí)現(xiàn)一個(gè)登錄程序,表單中包含有如下字段:

表單字段 說明
郵件地址 要求符合郵件地址的格式,如 user@qq.com
密碼 要求密碼至少包括 6 個(gè)字符
提交 將表單提交給服務(wù)器

用戶通過瀏覽器進(jìn)行登錄,界面如下所示:

圖片描述

用戶輸入郵件地址為 ‘tom’、密碼為 ‘123’,點(diǎn)擊登錄按鈕將表單提交給服務(wù)器,服務(wù)器進(jìn)行表單驗(yàn)證:

  • 驗(yàn)證郵件地址是否規(guī)范,并顯示驗(yàn)證失敗的信息——“請(qǐng)輸入正確的郵箱” ;
  • 驗(yàn)證密碼的長度,并顯示驗(yàn)證失敗的信息——“密碼至少包括 6 個(gè)字符”。

2.2 程序結(jié)構(gòu)

例子包括 2 個(gè)源文件,如下表所示:

程序 說明
app.py Flask 后端程序,實(shí)現(xiàn)表單驗(yàn)證
templates/login.html 登錄界面的模板

2.3 源程序下載

3. Flask 程序 app.py

3.1 安裝庫

使用如下命令安裝相關(guān)的庫:

$ pip3 install wtforms
$ pip3 install flask-wtf
$ pip3 install email-validator

3.2 引入庫

#!/usr/bin/python3
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField
from wtforms.validators import DataRequired, Length, Email, ValidationError

app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'

在這個(gè)程序中,引入如下類:

來自于模塊 功能
FlaskForm flask_wtf 登錄表單的基類
StringField wtforms 文本字段
PasswordField wtforms 密碼文本字段
SubmitField wtforms 表單提交按鈕
DateRequired wtforms 確保字段中有數(shù)據(jù)
Length wtforms 驗(yàn)證輸入字符串的長度
Email wtforms 驗(yàn)證電子郵件地址的格式是否正確
ValidationError wtforms 驗(yàn)證失敗時(shí),拋出此異常

在第 8 行,配置 Flask 應(yīng)用的選項(xiàng) ‘SECRET_KEY’ 用于防范 CSRF 攻擊,請(qǐng)參考 CSRF 攻擊的相關(guān)詞條。

3.3 定義登錄表單

class LoginForm(FlaskForm):
    email = StringField(
        label = '郵箱',
        validators = [
            DataRequired(message = '郵箱不能為空'),
            Email(message = '請(qǐng)輸入正確的郵箱')
        ]
    )

    password = PasswordField(
        label = '密碼',
        validators =[
            DataRequired(message = '密碼不能為空'),
            Length(min = 6, message = '密碼至少包括 6 個(gè)字符')
        ]
    )

    submit = SubmitField('登錄')

定義類 LoginForm,它繼承于 FlaskForm,用于描述登錄界面,登錄界面是一個(gè)表單,包含有 3 個(gè)字段:

  • email,顯示 label 為 ‘郵箱’,包括 2 個(gè)驗(yàn)證器:DataRequired 和 Email,message 參數(shù)為驗(yàn)證失敗的提示信息;
  • password,顯示 label 為 ‘密碼’,包括 2 個(gè)驗(yàn)證器:DataRequired 和 Length,message 參數(shù)為驗(yàn)證失敗的提示信息,min = 6 表示密碼的最小長度;
  • submit,提交按鈕,提交表單給服務(wù)端。

3.4 進(jìn)行表單驗(yàn)證

@app.route('/', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    print('form.validate_on_submit() =', form.validate_on_submit())
    print('form.email.label =', form.email.label)
    print('form.email() = ', form.email)
    print('form.email.errors =', form.email.errors)
    return render_template('login.html', form=form)

app.run(debug=True)

在第 1 行,設(shè)置以 GET 方法或者 POST 方法訪問路徑 / 時(shí),使用函數(shù) login() 進(jìn)行處理;在第 3 行,創(chuàng)建一個(gè)實(shí)例 form,表示用戶登錄的表單;在第 8 行,調(diào)用 render_template 渲染 login.html。

form 對(duì)象提供了如下方法和屬性:

屬性 說明
form.validate_on_submit() 表單驗(yàn)證函數(shù),返回值表示驗(yàn)證是否正確
form.email() 顯示 email 字段對(duì)應(yīng)的 HTML 代碼
form.email.label email 字段的 label
form.email.errors 驗(yàn)證 email 字段的失敗提示信息

在程序中打印 form 的屬性,當(dāng)用戶提交表單時(shí),在控制臺(tái)中顯示如下信息:

form.validate_on_submit() = False
form.email.label = <label for="email">郵箱</label>
form.email() =  <input id="email" name="email" required type="text" value="tom">
form.email.errors = ['請(qǐng)輸入正確的郵箱']

當(dāng)表單驗(yàn)證失敗時(shí),form.validate_on_submit() 返回為 False。form.email.errors 是一個(gè)列表,記錄了所有可能的錯(cuò)誤信息。

4. 模板文件 login.html

<html>
<meta charset='UTF-8'>
<h1>登錄</h1>
<form class="form" method="POST">
    <div>
        {{ form.email.label }}
        {{ form.email() }}
        <b>{{ form.email.errors[0] }}</b>
    </div>

    <div>
        {{ form.password.label }}
        {{ form.password() }}
        <b>{{ form.password.errors[0] }}</b>
    </div>

    <div>
        {{ form.submit() }}
    </div>

    {{ form.hidden_tag() }}
</form>
</html>

login.html 是用于描述登錄界面的模板,根據(jù) form 中字段 email 和 password 的屬性,它被渲染為如下的 HTML 文件:

<html>
<meta charset='UTF-8'>
<title>登錄</title>
<h1>登錄</h1>
<form class="form" method="POST">
    <div>
        <label for="email">郵箱</label> 
        <input id="email" name="email" required type="text" value="tom"> 
        <b>請(qǐng)輸入正確的郵箱</b>
    </div>

    <div>
        <label for="password">密碼</label> 
        <input id="password" name="password" required type="password" value=""> 
        <b>密碼至少包括 6 個(gè)字符</b>
    </div>

    <div>
        <input id="submit" name="submit" type="submit" value="登錄">
    </div>

    <input id="csrf_token" name="csrf_token" type="hidden" value="ImY2Y2NhMWNjZDRlYWE1ZDE2ODRiZDFlYzY5ZGNhNDIzZWJmNWQ0OTQi.X1Fo_w.13ad614Bw80RgPhc9RFdjZw7-q0">
</form>
</html>

這里注意兩點(diǎn):

  • form.email.errors 和 form.password.errors 是一個(gè)錯(cuò)誤信息列表,errors[0] 表示第一條錯(cuò)誤信息;
  • form.hidden_tag() 用于防范 CSRF 攻擊,生成 <input id=“csrf_token”/> 標(biāo)簽,請(qǐng)參考相關(guān)詞條。

5. 自定義驗(yàn)證器

5.1 簡介

在 Flask 中,可以自定義驗(yàn)證器實(shí)現(xiàn)特定的驗(yàn)證需求,例如:在驗(yàn)證密碼字段時(shí),要求密碼不能全部都是數(shù)字。

Flask 包含有兩種類型的驗(yàn)證器:行內(nèi)驗(yàn)證器和全局驗(yàn)證器。下面通過具體的例子說明如何實(shí)現(xiàn)自定義驗(yàn)證 “密碼是否全部是數(shù)字”。

5.2 行內(nèi)驗(yàn)證器

對(duì)前面小節(jié)的例子程序進(jìn)行如下的局部修改,修改類 LoginForm,增加一個(gè)成員函數(shù) validate_password,如下:

class LoginForm(FlaskForm):
    def validate_password(self, field):
        for char in field.data:
            print('!', char)
            if '0123456789'.find(char) < 0:
                return
        raise ValidationError('密碼不能全部是數(shù)字')

在第 2 行,定義成員函數(shù) validate_password,驗(yàn)證函數(shù)的形式為 validate_字段名,在驗(yàn)證字段數(shù)據(jù)時(shí)會(huì)調(diào)用這個(gè)方法來驗(yàn)證對(duì)應(yīng)的字段,在這里調(diào)用函數(shù) validate_password 驗(yàn)證字段 password。

在第 3 行到第 6 行,遍歷密碼字段 field 的每個(gè)字符,如果發(fā)現(xiàn)存在一個(gè)非數(shù)字的字符,則正常返回;如果所有的字符都是數(shù)字,則拋出異常 ValidationError。

當(dāng)用戶輸入的密碼全部都是數(shù)字時(shí),表單驗(yàn)證失敗,提示錯(cuò)誤信息為:‘密碼不能全部是數(shù)字’。

5.3 全局驗(yàn)證器

如果想要?jiǎng)?chuàng)建一個(gè)可重用的通用驗(yàn)證器,可以通過定義一個(gè)全局函數(shù)來實(shí)現(xiàn)。

對(duì)前面小節(jié)的例子程序進(jìn)行如下的局部修改,增加一個(gè)全局函數(shù) validate_password,如下:

def can_not_be_all_digits(form, field):
    for char in field.data:
        print('!', char)
        if '0123456789'.find(char) < 0:
            return
    raise ValidationError('密碼不能全部是數(shù)字')

函數(shù) can_not_be_all_digits 驗(yàn)證字段 field 是否全部是數(shù)字,代碼與上一個(gè)小節(jié)中的函數(shù) validate_password 完全相同。

同時(shí)修改類 LoginForm 的 PasswordField,如下:

class LoginForm(FlaskForm):
    password = PasswordField(
        label = '密碼',
        validators =[
            DataRequired(message = '密碼不能為空'),
            Length(min = 6, message = '密碼至少包括 6 個(gè)字符'),
            can_not_be_all_digits
        ]
    )

在第 7 行,validatros 中增加一個(gè)新的 validator——can_not_be_all_digits。當(dāng)用戶輸入的密碼全部都是數(shù)字時(shí),表單驗(yàn)證失敗,提示錯(cuò)誤信息為:‘密碼不能全部是數(shù)字’。

5.4 源程序下載

6. 小結(jié)

本小節(jié)講解了 Flask 的表單驗(yàn)證的概念和使用,總結(jié)如下:

圖片描述

使用 Flask 的表單驗(yàn)證功能,可以方便的驗(yàn)證表單中的字段的有效性,并渲染輸出表單的 HTML 代碼。