最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flask表單與表單驗(yàn)證實(shí)現(xiàn)流程介紹

 更新時(shí)間:2022年09月06日 10:54:56   作者:weixin_42576837  
這篇文章主要介紹了python中Flask?Web?表單的使用方法介紹,表單的操作是Web程序開(kāi)發(fā)中最核心的模塊之一,絕大多數(shù)的動(dòng)態(tài)交互功能都是通過(guò)表單的形式實(shí)現(xiàn)的。更多介紹需要的小伙伴可以參考下面文章內(nèi)容

表單介紹

說(shuō)到表單,在HTML中表單的創(chuàng)建時(shí)通過(guò)<form>標(biāo)簽實(shí)現(xiàn)的,在<form>標(biāo)簽內(nèi)部,字段通過(guò)使用<input>標(biāo)簽等定義。比如一個(gè)表單內(nèi)部有用戶名,密碼框這些,都是通過(guò)<input><label>標(biāo)簽等實(shí)現(xiàn)的。

一個(gè)簡(jiǎn)單的表單:

<form>
First name:<br>
<input type="text" name="firstname">
<br>
Last name:<br>
<input type="text" name="lastname">
</form>

將表單提交給服務(wù)端處理時(shí),服務(wù)端需要驗(yàn)證表單中的字段的取值是否符合要求。

在 Python 的 Web 開(kāi)發(fā)中,表單內(nèi)部的字段標(biāo)簽之類的,就不再使用HTML標(biāo)簽來(lái)寫(xiě)了,而是通過(guò)python類實(shí)現(xiàn)。

WTForms在python中使用類定義表單,然后直接通過(guò)類定義生成對(duì)應(yīng)的HTML代碼,這種方式更加方便,而且使表單更易于重用。除非是非常簡(jiǎn)單的程序,或者想讓表單的定義更加靈活,否則一般不會(huì)在模板中直接使用HTML代碼寫(xiě)表單。

WTForms 和 Flask-WTF

WTForms 是一個(gè)靈活的表單驗(yàn)證和表單渲染的庫(kù),它的主要功能:

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

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

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

創(chuàng)建表單

下面直接用代碼講解如何創(chuàng)建表單。

首先,我們的目標(biāo)是這樣一個(gè)頁(yè)面

一個(gè)簡(jiǎn)單的登錄頁(yè)面,讓用戶輸入用戶名,密碼,同時(shí)對(duì)用戶名和密碼進(jìn)行驗(yàn)證,驗(yàn)證成功就輸出,驗(yàn)證不成功需要重新輸入,并提示錯(cuò)誤信息。

首先,這是一個(gè)表單,表單內(nèi)有一些文本,有文本框,有登錄按鈕,這些都是通過(guò)python中的表單類創(chuàng)建的,使用的正是flask-wtf模塊創(chuàng)建的。

先導(dǎo)入需要的模塊

#導(dǎo)入表單類
from flask_wtf import FlaskForm
#導(dǎo)入字段類
from wtforms import StringField,SubmitField,PasswordField
#導(dǎo)入驗(yàn)證器類
from wtforms.validators import DataRequired,Length,Regexp
class LoginForm(FlaskForm):
    '''
    這些字段對(duì)象會(huì)被渲染為html標(biāo)簽
    實(shí)例化一個(gè)文本字段對(duì)象,設(shè)置參數(shù)
    label:這個(gè)值可以拿出來(lái)放在標(biāo)簽前面顯示
    validators=[]驗(yàn)證器列表,實(shí)例化的驗(yàn)證器對(duì)象,里面又可以設(shè)置參數(shù)
    '''
    #用戶名字段
    username = StringField(
        label='用戶名',
        validators=[
            DataRequired(message='用戶名不能為空'),
            Length(3,20,message='用戶名長(zhǎng)度在3-20個(gè)字符')
        ]
    )
    password = PasswordField(
        label='密碼',
        validators=[
            DataRequired(message='密碼不能為空'),
            Length(3,20,message='密碼長(zhǎng)度在3-20個(gè)字符'),
 			Regexp(r'^[a-z0-9A-Z]+$',message='密碼只能有字母,數(shù)字,下劃線組成')
        ]
    )
    submit = SubmitField(label='登錄')

我們創(chuàng)建了一個(gè)類LoginForm,它是一個(gè)表單類,繼承了FlaskForm,這個(gè)表單中包含一個(gè)用戶名username字段,密碼password字段,還有一個(gè)提交按鈕submit,這三個(gè)字段作為了類LoginForm的三個(gè)屬性。

表單字段

我們發(fā)現(xiàn)用戶名,密碼這些實(shí)際是文本框,既然不用HTML代碼實(shí)現(xiàn),那么怎么實(shí)現(xiàn)呢?

使用的就是WTForms中的各種字段類,比如這里:

username = StringField()

StringField()是WTForms 支持表單字段類,它表示文本字段,這樣一個(gè)字段會(huì)被渲染為

<input id="username" name="username" type="text" value="">

注意:實(shí)例化對(duì)象的名稱是username ,被渲染后的input標(biāo)簽中的idname屬性值都叫username

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

這只是一部分,還有很多其他支持的字段。

接著看代碼:

    username = StringField(
        label='用戶名',
        validators=[
            DataRequired(message='用戶名不能為空'),
            Length(3,20,message='用戶名長(zhǎng)度在3-20個(gè)字符')
        ]
    )

驗(yàn)證器

StringField類需要傳遞一些參數(shù):

label='用戶名' ,這個(gè)參數(shù)可以直接在模板頁(yè)面中顯示,使用form.username.label,把它放在文本框的前面,像下面這樣:

validators=[ ] 這個(gè)參數(shù)表示對(duì)這個(gè)字段使用的驗(yàn)證器列表。驗(yàn)證器就是對(duì)這個(gè)字段使用那些驗(yàn)證,比如這里DataRequired,Length兩個(gè)驗(yàn)證器類,同樣驗(yàn)證器類需要實(shí)例化然后傳入?yún)?shù)。比如:

Length(3,20,message='用戶名長(zhǎng)度在3-20個(gè)字符')

限定長(zhǎng)度在3-20字符,如果驗(yàn)證不通過(guò),就彈出錯(cuò)誤信息:message='用戶名長(zhǎng)度在6-20個(gè)字符'。

驗(yàn)證器也有很多類型,常見(jiàn)的驗(yàn)證器類有:

還可以自定義驗(yàn)證器類等等。

我們創(chuàng)建了一個(gè)單獨(dú)的文件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='用戶名長(zhǎng)度在3-20個(gè)字符')
        ]
    )
    password = PasswordField(
        label='密碼',
        validators=[
            DataRequired(message='密碼不能為空'),
            Length(3,20,message='密碼長(zhǎng)度在3-20個(gè)字符'),
            Regexp(r'^[a-z0-9A-Z]+$',message='密碼只能有字母,數(shù)字,下劃線組成')
        ]
    )
    submit = SubmitField(label='登錄')

表單類創(chuàng)建好之后,可以做一個(gè)簡(jiǎn)單的測(cè)試:

把這個(gè)表單顯示出來(lái)

首先,我們?cè)赼pp.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 攻擊,具體的我也不清楚,就不再細(xì)說(shuō)了,總之需要設(shè)置

接著,在根路由下/,有視圖函數(shù)login,訪問(wèn)這個(gè)路由的方法可以是GET,或者POST。首先假設(shè)是GET,我們就需要把之前的表單渲染出來(lái),具體的做法就是:

使用創(chuàng)建的表單類LoginForm實(shí)例化一個(gè)表單對(duì)象loginform ,如果請(qǐng)求方法是GET,就去渲染login.html,然后表單對(duì)象作為參數(shù)傳遞過(guò)去。所以我們還需要設(shè)計(jì)一下login.html文件。

login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄頁(yè)面</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>

這里使用了一個(gè)表格布局,然后表單的action="{{ url_for('login') }}" method="post",設(shè)置了表單的提交路徑,以及提交方法。

    <td>{{ form.username.label }}</td>#拿到username的label值顯示出來(lái)
    <td>{{ form.username }}</td>#顯示username這個(gè)字段
    <td>{% for err in form.username.errors %}#這是錯(cuò)誤信息,如果驗(yàn)證不通過(guò)會(huì)顯示錯(cuò)誤信息
        {{ err }}
        {% endfor %}
    </td>

最后,還要注意到: {{ form.hidden_tag() }}, 用于防范 CSRF 攻擊,生成 <input id=“csrf_token”/> 標(biāo)簽??傊仨氁由?,不加上,后面驗(yàn)證數(shù)據(jù)的時(shí)候會(huì)出問(wèn)題。

接著,運(yùn)行app.py,訪問(wèn)根路徑/,則是GET方法訪問(wèn),會(huì)渲染出login.html文件。

接著,我們需要實(shí)現(xiàn),用戶輸入數(shù)據(jù),我們進(jìn)行驗(yàn)證,驗(yàn)證不成功就提示錯(cuò)誤信息,驗(yàn)證成功就登錄成功。

回到表單類中,我們可以發(fā)現(xiàn)使用的驗(yàn)證器有這幾種:

其中,DataRequired,Length直接被渲染為HTML中input標(biāo)簽的屬性:

maxlength="" minlength="" required

這時(shí)候驗(yàn)證就是在瀏覽器上完成的了,而不是在服務(wù)器??蛻舳朔绞娇梢詫?shí)時(shí)動(dòng)態(tài)的提示用戶輸入是否正確,只有用戶輸入正確后才會(huì)將表單數(shù)據(jù)發(fā)送給服務(wù)器??蛻舳蓑?yàn)證可以增強(qiáng)用戶體驗(yàn),降低服務(wù)器負(fù)載。

參考書(shū)上說(shuō),F(xiàn)lask程序中使用WTForms實(shí)現(xiàn)的就是服務(wù)器驗(yàn)證,但是有些字段又會(huì)被渲染為HTML5的屬性,所以也不全是服務(wù)器驗(yàn)證。

這就是瀏覽器給出的驗(yàn)證提示

但是正則驗(yàn)證器,確實(shí)是在服務(wù)端完成驗(yàn)證的

Regexp(r'^[a-z0-9A-Z]+$',message='密碼只能有字母,數(shù)字,下劃線組成')

那么怎么在服務(wù)器驗(yàn)證數(shù)據(jù)呢,首先,我們的數(shù)據(jù)會(huì)提交到/路徑,使用的是POST方法。

表單類對(duì)象loginform,有一個(gè)驗(yàn)證方法,loginform.validate(),調(diào)用這個(gè)方法時(shí),會(huì)去調(diào)用你每一個(gè)字段中使用的每一個(gè)驗(yàn)證器去驗(yàn)證數(shù)據(jù),全部驗(yàn)證通過(guò)返回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)
  • 如果請(qǐng)求方法時(shí)GET,直接渲染表單
  • 如果請(qǐng)求方法時(shí)POST,并且loginform.validate()==True,表示驗(yàn)證通過(guò),這時(shí)候我們返回登錄成功,同時(shí)使用loginform.username.data可以拿到用戶輸入的用戶名。
  • 否則,驗(yàn)證失敗,再次渲染這個(gè)表單,注意:這時(shí)候,調(diào)用了validate()方法,返回False,產(chǎn)生了錯(cuò)誤信息,錯(cuò)誤信息在form.username.errors,是一個(gè)列表,這時(shí)候login.html中的錯(cuò)誤信息列表就是有輸出了。

測(cè)試一下:我的密碼字段設(shè)置了正則驗(yàn)證,只允許輸入字母數(shù)字下劃線,而且字符個(gè)數(shù)在3-20個(gè)。

首先,不填寫(xiě)字段,瀏覽器端會(huì)自動(dòng)驗(yàn)證

輸入正確格式的密碼:

輸入錯(cuò)誤格式的密碼:

到此這篇關(guān)于Flask表單與表單驗(yàn)證實(shí)現(xiàn)流程介紹的文章就介紹到這了,更多相關(guān)Flask表單內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python選擇網(wǎng)卡發(fā)包及接收數(shù)據(jù)包

    Python選擇網(wǎng)卡發(fā)包及接收數(shù)據(jù)包

    今天小編就為大家分享一篇關(guān)于Python選擇網(wǎng)卡發(fā)包及接收數(shù)據(jù)包,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • 淺談Python數(shù)學(xué)建模之?dāng)?shù)據(jù)導(dǎo)入

    淺談Python數(shù)學(xué)建模之?dāng)?shù)據(jù)導(dǎo)入

    數(shù)據(jù)導(dǎo)入是所有數(shù)模編程的第一步,比你想象的更重要。Python 語(yǔ)言中數(shù)據(jù)導(dǎo)入的方法很多。對(duì)于數(shù)學(xué)建模問(wèn)題編程來(lái)說(shuō),選擇什么方法最好呢?答案是:沒(méi)有最好的,只有最合適的。對(duì)于不同的問(wèn)題,不同的算法,以及所調(diào)用工具包的不同實(shí)現(xiàn)方法,對(duì)于數(shù)據(jù)就會(huì)有不同的要求
    2021-06-06
  • Django中使用Redis配置緩存的方法步驟

    Django中使用Redis配置緩存的方法步驟

    本文主要介紹了Django中使用Redis配置緩存的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • django 將model轉(zhuǎn)換為字典的方法示例

    django 將model轉(zhuǎn)換為字典的方法示例

    平常的開(kāi)發(fā)過(guò)程中不免遇到需要把model轉(zhuǎn)成字典的需求,這篇文章主要介紹了Django model轉(zhuǎn)字典的方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2018-10-10
  • python 多線程中子線程和主線程相互通信方法

    python 多線程中子線程和主線程相互通信方法

    今天小編就為大家分享一篇python 多線程中子線程和主線程相互通信方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • Python中串口通信庫(kù)pyserial基礎(chǔ)知識(shí)

    Python中串口通信庫(kù)pyserial基礎(chǔ)知識(shí)

    Python的pyserial庫(kù)是一個(gè)用于通過(guò)串口進(jìn)行通信的庫(kù),下面這篇文章主要給大家介紹了關(guān)于Python中串口通信庫(kù)pyserial基礎(chǔ)知識(shí)的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • python urllib和urllib3知識(shí)點(diǎn)總結(jié)

    python urllib和urllib3知識(shí)點(diǎn)總結(jié)

    在本篇內(nèi)容里小編給大家分享了一篇關(guān)于python urllib和urllib3知識(shí)點(diǎn)總結(jié)內(nèi)容,對(duì)此有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-02-02
  • Python報(bào)錯(cuò)之如何解決matplotlib繪圖中文顯示成框框問(wèn)題

    Python報(bào)錯(cuò)之如何解決matplotlib繪圖中文顯示成框框問(wèn)題

    這篇文章主要介紹了Python報(bào)錯(cuò)之如何解決matplotlib繪圖中文顯示成框框問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Python3基礎(chǔ)之基本數(shù)據(jù)類型概述

    Python3基礎(chǔ)之基本數(shù)據(jù)類型概述

    這篇文章主要介紹了Python3的基本數(shù)據(jù)類型,需要的朋友可以參考下
    2014-08-08
  • Python讀取Excel數(shù)據(jù)并生成圖表過(guò)程解析

    Python讀取Excel數(shù)據(jù)并生成圖表過(guò)程解析

    這篇文章主要介紹了Python讀取Excel數(shù)據(jù)并生成圖表過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06

最新評(píng)論

三台县| 确山县| 长阳| 保德县| 婺源县| 合江县| 中卫市| 安西县| 福海县| 志丹县| 武胜县| 芮城县| 东乡族自治县| 新化县| 江津市| 鄂托克旗| 神农架林区| 通海县| 汶川县| 抚松县| 崇义县| 驻马店市| 陵川县| 睢宁县| 确山县| 普兰县| 兴化市| 昆山市| 柯坪县| 祁门县| 东明县| 鲁山县| 鱼台县| 六盘水市| 于都县| 延长县| 山西省| 平泉县| 浮梁县| 邓州市| 准格尔旗|