擴展Flask-WTF繼承了WTFforms,使用它能夠在flask中更方便的使用WTForms。Flask-WTF將表單數據解析、CSRF保護、文件上傳等功能與Flask集成。html
激活pipenv環境python
看下環境中安裝了什麼shell
pipenv install flask-wtf,安裝flask-wtfflask
裝完了後:app
flask-wtf默認爲每一個表單啓用CSRF保護,它爲咱們自動生成和驗證CSRF令牌。默認狀況下,fflask-wtf使用程序祕鑰來對CSRF令牌進行簽名(token),因此咱們須要爲程序設置祕鑰:ui
app.secret_key = ‘secret string’spa
使用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屬性值。code
字段屬性名稱大小寫敏感,不能如下劃線或validate開頭。orm
這裏的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。
以咱們使用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),才能實例化運行上面的程序,激活上下文能夠經過如下方式:
一、 pipenv shell 激活虛擬環境
二、到appForm.py所在目錄:D:\flask\FLASK_PRACTICE
三、運行python進入python命令行模式
四、激活程序上下文:
>>> from appForm import app
>>> from flask import current_app
>>> app_ctx=app.app_context()
>>> app_ctx.push()
>>> current_app.name
'appForm'
五、激活請求上下文:
>>> from appForm import app
>>> from flask import request
>>> app_re=app.test_request_context('/html')
>>> app_re.push()
>>> request.method
'GET'
六、把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屬性值。