bootstrap的表单验证 vue_第45天:Web表单
在了解了 Flask Bootstrap 基本框架之后,我們來了解一下 Flask 框架的 表單( form ),以幫助我們創建交互式的 Web 應用,最后會有個提交個人信息的例子。
Flask-WTF 是 Flask 框架的一個擴展,用來做表單的交互,是對 WTForms 的集成,默認支持 CSRF 安全簽名,并且繼承文件上傳功能。
安裝
使用 pip 安裝
pip install Flask-WTF驗證
>>> from flask_wtf import FlaskForm>>>小試牛刀
創建表單類
Flask-WTF 能將 WTForms 集成到 Flask 應用中,創建一個 app.py 主代碼文件,例如:
from flask_wtf import FlaskFormfrom wtforms import StringFieldfrom wtforms.validators import DataRequiredclass MyForm(FlaskForm): name = StringField('name', validators=[DataRequired()])MyForm 是自定義的類,繼承自 FlaskForm,其中定義了一個字段 name,標題是 name, 且設置為非空。
表單模板
接下來創建一個表單模板 submit.html,例如:
{{ form.csrf_token }} {{ form.name.label }} {{ form.name(size=20) }}其中 form.csrf_token 是 Flask-WTF 提供的一個防止跨站請求偽造的隱藏字段。原理是將一個密鑰根據請求特征加密,在表單提交時一起送到服務器端,作校驗。
密鑰串與多種定義方式,為了方便,這里將密鑰串定義在應用上:
app.secret_key = 'abc'注意:上示例僅作演示說明,不能在生產系統中用這樣簡單的密鑰
之后則是對字段 name 的模板定義,經過渲染會替換成 Html 控件。
定義視圖函數
視圖函數首先需要將表單渲染出來,另外要對表單的提交作驗證,當然視圖函數與提交驗證函數也可不是同一個:
@app.route('/', methods=('GET', 'POST'))def submit(): form = MyForm() if form.validate_on_submit(): return redirect('/success') return render_template('submit.html', form=form)提交表單一般都是 POST 方法,所以要確保視圖函數支持 POST
視圖函數中實例化一個 MyForm,值得注意的時,FlaskForm 示例化時會使用 request 中的 form 來初始化,所以在下面才可以直接來校驗表單
validate_on_submit 方法是 is_submitted 和 validate 的聯合校驗,后面會詳述
如果驗證通過將跳轉到 /success,如果沒有通過,用 form 來渲染 submit.html 模板,
運行
在主代碼 ?app.py 中加入啟動方法:
if __name__ == '__main__': app.run(debug=True)然后運行,如果一起正常,訪問 localhost:5000, 就能看輸入框和提交按鈕,點擊提交,會跳轉到 /success 或者提升必填。
表單
FlaskForm 是 WTForms Form 的子類,可以用來定一個表單,定義表單中的字段,驗證方式等,作為一個 Flask 和 Html 之間的一個數據載體。
另外 FlaskForm 集成了 CSRF 校驗,方便編寫程序的同時,提高訪問安全性。定義 Form 對象時不用明確聲明 CSRF 字段,只需要在表單模板中填寫 ?form.csrf_token 就行,提交表單時,視圖函數會自動對 CSRF 進行校驗。
FlaskForm 實例化參數中有個 formdata 參數,用來設定 Form 中字段的值,在視圖函數中,可以不提供 formdata,會將 request.form 或者 request.files 中獲取,作為 formdata 參數,這就是視圖函數中實例化 Form 時,不帶任何參數,在后面還能方法 Form 對象內容的原因。
字段及驗證
FlaskForm 從 0.9.0 版本開始,不再從 WTForms 中導入任何東西,所以大部分字段和校驗方法都直接引用自 WTForms,如:
from wtforms import StringField, IntergreField, validators- 常用的字段
 
| StringField | 文本字段 | 
| IntergreField | 文本字段,要求輸入的時數字 | 
| PasswordField | 文本字段,輸入內容會轉會為小黑點 | 
| DateField | 文本字段,輸入指定日期格式的字符串會轉會為日期類型 | 
| RadioField | 單選字段 | 
| SelectField | 選擇字段 | 
| SelectMultipleField | 多項選擇字段 | 
| SubmitField | 表單的提交按鈕 | 
- 常用驗證
 
| DataRequired | 必填字段 | 
| 電子郵箱地址驗證 | |
| EqualTo | 驗證與其他指定字段值是否相等 | 
| Length | 輸入字符串長度限制 | 
| NumberRange | 輸入數值大小限制 | 
| URL | 網站格式驗證 | 
例如定義一個 MyForm 表單類:
class MyForm(FlaskForm): name = StringField(label='姓名', validators=[InputRequired()]) city = StringField('城市', validators=[validators.Length(min=4, max=25, message='輸入的長度不符合要求')]) birthday = DateField(label='生日', format="%Y-%m-%d", validators=[DataRequired('日期格式不正確')]) gender = RadioField(label='性別', choices=[(1, 'male'), (2, 'female')]) interest = SelectMultipleField(label='興趣', choices=[(1, 'Football'), (2, 'Movies'), (3, 'Reading')])如果字段值驗證失敗,會將錯誤信息存放在字段的 errors 屬性中,errors 是個列表,元素是每一個驗證出現的問題信息,通過設定驗證的 message 參數指定。
要完整的在模板中定義字段以及錯誤信息,是件乏味的事情,這里通過一個自定義的模板宏來完成:
{% macro render_field(field) %} {{ field.label }}: {{ field(**kwargs)|safe }} {% if field.errors %} {% for error in field.errors %} {{ error }} {% endfor %} {% endif %} {% endmacro %}文件上傳
上傳文件,是表單應用必不可少的,可以通過 FileField 字段來設置,因為需要視圖函數對上傳的文件進行處理,所以這里單獨作說明
定義一個有上傳文件字段的表單類:
from flask_wtf.file import FileFieldclass PhotoForm(FlaskForm): photo = FileField('上傳照片')視圖函數定義為:
@app.route('/upload', methods=['GET', 'POST'])def upload(): form = PhotoForm() filepath = None if form.validate_on_submit(): filename = secure_filename(form.photo.data.filename) file = form.photo.data filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save( filepath ) else: filename = None return render_template('photo.html', form=form, filename= filename)在通過驗證之后,用方法 secure_filename 對上傳文件名作安全處理,這是很有必要的,以防止通過文件名注入, 這個方法從庫 werkzeug 中導入,這個庫會在在安裝 Flask 時一起被安裝。
之后拿到上傳文件的數據,這是已經經過 Flask 轉化的 File 對象,可以直接調用 save 方法存儲上傳的文件。
app.config['UPLOAD_FOLDER'] 定義了文件存儲的位置,如:
app.config['UPLOAD_FOLDER'] = './upload'最后新建一個模板文件 upload.html:
{{ form.csrf_token() }} {{ form.photo() }}注意模板中 form 的編碼類型必須設置為 multipart/form-data
Bootstrap
雖然 FlaskForm 使用起來已經很方便了,但是還是有很多需要重復編寫的地方,以及展示效果不夠美觀的問題,借助 Bootstrap-flask 將解決這些問題。
之前對 Bootstrap-flask 介紹中說國,Bootstrap-flask 主要是定義了很多模板宏,減少重復的編碼,對于表單,同樣提供了很多宏
首先在模板中導入 bootstrap 的 Form 相關宏:
{% from 'bootstrap/form.html' import render_form, render_form_row, render_field %}- render_form 接受一個 Form 對象,將其渲染成 Html 表單,是最省事的,例如:
 
- render_field 接受一個 Field, 將其渲染成一個表單的字段:
 
- render_form_row 接受一個 Field 列表,將列表中的字段渲染到一行
 
模板代碼如下:
{% from 'bootstrap/form.html' import render_form, render_form_row, render_field %}{{ bootstrap.load_css() }}render_form
{{ render_form(form) }}render_form_row
{{ render_form_row([form.name, form.city]) }} {{ render_form_row([form.gender, form.birthday]) }} {{ render_form_row([form.interest]) }}render_field
{{ render_field(form.name) }} {{ render_field(form.gender) }} {{ render_field(form.interest) }}先導入表單相關的宏,然后加入 Bootstrap 的樣式,之后是各個宏的使用
總結
本節課程簡單介紹了 Flask 中表單的處理方式和方法,包括 FlaskForm,WTForms和一些常用的字段,最后說明了 Bootstrap-flask 對表單的支持,以便是 Web 開發更高效。
示例代碼:Python-100-days-day045
參考
- https://flask-wtf.readthedocs.io/en/stable/
 - https://dormousehole.readthedocs.io/en/latest/patterns/wtforms.html
 - https://www.cnblogs.com/haiyan123/p/8254228.html
 
系列文章
????第44天:Flask 框架集成Bootstrap
????第43天:Python filecmp&difflib模塊
????第42天:Python paramiko 模塊
????第41天:Python operator 模塊
????第0-40天:從0學習Python 0-40合集PS:公號內回復 :Python,即可進入Python 新手學習交流群,一起100天計劃!-END-Python 技術關于 Python 都在這里總結
以上是生活随笔為你收集整理的bootstrap的表单验证 vue_第45天:Web表单的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 花呗分期如何提前还款
 - 下一篇: 360借条手动还款在哪里