flask 使用Flask-WTF處理表單 --


 

使用Flask-WTF處理表單

 擴展Flask-WTF繼承了WTFforms,使用它可以在flask中更方便的使用WTForms。Flask-WTF將表單數據解析、CSRF保護、文件上傳等功能與Flask集成。

 

先用pipenv安裝flask-wtf及其依賴:

激活pipenv環境

 

看下環境中安裝了什么

pipenv install flask-wtf,安裝flask-wtf

 

 

裝完了后:

 

flask-wtf默認為每個表單啟用CSRF保護,它為我們自動生成和驗證CSRF令牌。默認情況下,fflask-wtf使用程序秘鑰來對CSRF令牌進行簽名(token),所以我們需要為程序設置秘鑰:

app.secret_key = ‘secret string’

定義WTForms表單來

使用WTForms創建表單時,表單由python類表示,這個類繼承從STForms導入的Form類。一個表單由若干個輸入字段組成,這些字段分別用表單類的類屬性來表示(字段即field,可以簡單理解為表單內的輸入框、按鈕等部件),下面定義了一個LoginForm類,最終會生成像之前定義的HTML表單:

from wtforms import Form, StringField, PasswordField, BooleanField, SubmitField
from wfforms.validators import DataRequired, Length
class LoginForm(Form):
    username = StringField('Username', validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired(), Length(8,128)])
    remember = BooleanField('Remember me')
    submit = SubmitField('Log in')

每個字段屬性通過實例化WTForms提供的字段類來表示。字段屬性的名稱將作為對應HTML<input>元素的name屬性及id屬性值。

字段屬性名稱大小寫敏感,不能以下划線或validate開頭。

這里的LoginForm表單類中定義了四個字段:文本字段StringField、密碼字段Pawword-Field、勾選框字段BooleanField和提交按鈕字段SubmitField。字段類從wtforms包導入,有些字段最終生成的HTML代碼相同,不過WTForms會在表單提交后根據表單類中字段的類型對數據進行處理,轉換成對應的python類型,以便在python腳本中對數據進行處理。

 

常用的WTForms字段如下表:

 

通過實例化字段類時傳入的參數,我們可以對字段進行設置,字段類構造方法接受的常用參數如下表:

 

在WTForms中,驗證器(validator)是一系列用於驗證字段數據的類,我們在實例化字段類時使用validators關鍵字來指定附加的驗證器列表。驗證器從wtforms.validators模塊中導入,常用的驗證器,如下表:

 

在實例化驗證類時,message參數用來傳入自定義錯誤消息,如果有設置則使用內置的英文錯誤消息

 

validators參數接收一個可調用對象組成的列表。內置的驗證器通過實現了__call__()方法的類表示,所以我們需要在驗證器后添加括號。

 

在name和password字段里,我們都是用了DataRequired驗證器,用來驗證輸入的數據是否有效。另外,password字段里還添加了一個Length驗證器,用來驗證輸入的數據長度是否在給定的范圍內。驗證器的第一個參數一般為錯誤提示消息,我們可以使用message關鍵字傳遞參數,通過傳入自定義錯誤信息來覆蓋內置消息,比如:

name = StringField(‘Your Name’, validators=[DataRequired(message=u’名字不能為空’)])

 

當使用Flask-WTF定義表單時,我們仍然使用WTForms提供的字段類和驗證器,創建的方式也完全相同,只不過表單類要繼承Flask-WTF提供的FlaskForm類。FlaskForm類繼承自Form類,進行了一些設置,並附加了寫輔助方法,以便與Flask集成。

我們創建一個forms.py文件(form/forms.py),用來存儲各種表單類。

下面例子是繼承FlaskForm類的LoginForm表單:

 

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import DataRequired, Length

class LoginForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired(), Length(8, 128)])
    remember = BooleanField('Remember me')
    submit = SubmitField('Log in')

配置鍵WTF_CSRF_ENABLED用來設置是否開啟CSRF保護,默認為True。Flask-WTF會自動在實例化表單時添加一個包含CSRF令牌值的隱藏字段,字段名為csrf_token。

輸出HTML代碼

以我們使用WTForms創建的LoginForm為例,實例化表單類,然后將實例屬性轉換成字符串或直接調用就可以獲取表單字段對應的HTML代碼(需要在虛擬環境激活上下文):

>>> form = LoginForm()

>>> form.username()

u'<input id="username" name="username" required type="text" value="">'

>>> form.submit()

u'<input id="submit" name="submit" type="submit" value="Log in">'

>>> form.password()

u'<input id="password" name="password" required type="password" value="">'

>>> form.remember()

u'<input id="remember" name="remember" type="checkbox" value="y">'

 

字段的<label>元素的HTML代碼則可以通過”form.字段名.label”的形式獲取:

>>> form.username.label()

u'<label for="username">Username</label>'

>>> form.submit.label()

u'<label for="submit">Log in</label>'

 

在虛擬環境下,需要激活程序上下文(app_context)和請求上下文(request_context),才能實例化運行上面的程序,激活上下文可以通過以下方式:

1、  pipenv shell 激活虛擬環境

2、到appForm.py所在目錄:D:\flask\FLASK_PRACTICE

3、運行python進入python命令行模式

4、激活程序上下文:

>>> from appForm import app

>>> from flask import current_app

>>> app_ctx=app.app_context()

>>> app_ctx.push()

>>> current_app.name

'appForm'

 

5、激活請求上下文:

>>> from appForm import app

>>> from flask import request

>>> app_re=app.test_request_context('/html')

>>> app_re.push()

>>> request.method

'GET'

 

6、把LoginForm()類定義運行一下

>>> from flask_wtf import FlaskForm

>>> from wtforms import StringField, PasswordField, BooleanField, SubmitField

>>> from wtforms.validators import DataRequired, Length

>>> 

>>> class LoginForm(FlaskForm):

...     username = StringField('Username', validators=[DataRequired()])

...     password = PasswordField('Password', validators=[DataRequired(), Length(8, 128)])

...     remember = BooleanField('Remember me')

...     submit = SubmitField('Log in')

 

之后就可以實例化這個類,做其他的事情了

添加額外的屬性

在創建HTML表單時,我們經常會需要使用HTML<input>元素的其他屬性來對字段進行設置。比如class屬性設置對應的CSS類為字段添加樣式;添加placeholder屬性設置占位文本。默認情況下WForms輸出的字段HTML代碼只會包含id和name屬性,屬性值均為表單類中對應的字段屬性名稱。如果要添加額外的屬性,通常有兩種方法。

 

使用render_kw屬性

比如下面為username字段使用render_kw設置了placeholder HTML屬性:

username = StringField(‘Username’ render_kw={‘placeholder’: ‘Your Username’})

這個字段被調用后輸出的HTML代碼是:

<input type=”text” id=”username” name=”username” placeholder=”Your Username”>

 

調用字段時傳入

在調用字段屬性時,通過添加括號使用關鍵字參數的形式也可以傳入字段額外的HTML屬性:

>>> form.username()

u'<input id="username" name="username" required type="text" value="">'

>>> form.username(style='width:200px;',class_='bar')

u'<input class="bar" id="username" name="username" required style="width:200px;" type="text" value="">'

class是pyhton的保留字,我們使用class_來代替class,渲染后的<input>會獲得正確的classl屬性,在模板中調用時則可以直接使用class。

 

通過上面的方法也可以修改id和name屬性,但表單被提交后,WTForms需要通過name屬性來獲取對應的數據,所以不能修改name屬性值。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM