Flask-WTF擴展能夠把處理web表單的過程變成一種愉悅的體驗。html
默認狀況下,Flask-WTF可以保護全部表單免受跨站請求僞造的攻擊。惡意網站把請求發送到被攻擊者已登陸的網站時就會引發CSRF攻擊。python
爲了實現CSRF保護,Flask-WTF須要程序設置一個密鑰。Flask-WTF使用這個密鑰生成加密令牌,再用令牌驗證請求中表單數據的真僞。設置密鑰的方法以下所示:web
app = Flask(__name__) app.config['SECRET_KEY']='hard to guess string'
使用Flask-WTF時,每一個web表單都由一個繼承自Form的類表示。這個定義表單中的一組字段,每一個字段都用對象表示。字段對象可附屬一個或多個驗證函數。驗證函數用來驗證用戶提交的輸入值是否符合要求。正則表達式
#!/usr/bin/env python #簡單的web表單,包含一個文本字段和一個提交按鈕 from flask_wtf import Form from wtforms import StringField,SubmitField from wtforms.validators import Required class NameForm(Form): name = StringField('What is your name?',validators=[Required()]) submit = SubmitField('Submit')
StringField類表示屬性爲type="text"的<input>元素,SubmitField類表示屬性爲type="submit"的<input>元素。flask
WTForms支持的HTML標準字段bootstrap
字段類型 | 說明 |
StringField | 文本字段 |
TextAreaField | 多行文本字段 |
PasswordField | 密碼文本字段 |
HiddenField | 隱藏文本字段 |
DateField | 文本字段,值爲datetime.date格式 |
IntegerField | 文本字段,值爲整數 |
FloatField | 文本字段,值爲浮點數 |
SelectField | 下拉列表 |
SubmitField | 表單提交按鈕 |
WTForms驗證函數網絡
驗證函數 | 說明 |
驗證電子郵件地址 | |
EqualTo | 比較兩個字段的值,經常使用於要求輸入兩次密碼進行確認的狀況 |
IPAddress | 驗證IPv4網絡地址 |
Length | 驗證輸入字符串的長度 |
NumberRange | 驗證輸入的值在數字範圍內 |
Optional | 無輸入值時跳過其餘驗證函數 |
Required | 確保字段中有數據 |
Regexp | 使用正則表達式驗證輸入值 |
URL | 驗證URL |
AnyOf | 確保輸入值在可選值列表中 |
NoneOf | 確保輸入值不在可選值列表中 |
表單字段是可用的,在模板中調用後會渲染成HTML。假設視圖函數把一個NameForm實例經過參數form傳入模板,在模板中能夠生成一個簡單的表單,以下所示:session
<form method="POST"> {{ form.hidden_tag() }} {{ form.name.label }} {{ form.name() }} {{ form.submit() }} </form>
<form method="POST"> {{ form.hidden_tag() }} {{ form.name.label }} {{ form.name(id='my-text-field') }} {{ form.submit() }} </form>
Flask-Bootstrap提供了一個很是高端的輔助函數,可使用Bootstrap中預先定義好的表單樣式渲染整個Flask-WTF表單,而這些操做只需調用一次便可完成。app
{% import "boostrap/wtf.html" as wtf %} {{ wtf.quick_form(form) }}
#使用Flask-WTF和Flask-Bootstrap渲染表單 {% extends "base.html" %} {% import "bootstrap/wtf.html" as wtf %} {% block title %}Flasky{% endblock %} {% block page_content %} <div class="page-header"> <h1>Hello,{% if name %}{{ name }}{% else %}Stranger{% endif %}</h1> </div> {{ wtf.quick_form(form) }} {% endblock %}
@app.route('/',methods=['GET','POST']) def index(): name = None form = NameForm() if form.validate_on_submit(): name = form.name.data form.name.data = '' return render_template('index.html',form=form,name=name)
app.route修飾器中添加的methods參數告訴Flask在URL映射中把這個視圖函數註冊爲GET和POST請求的處理程序。若是沒指定methods參數,就只把視圖函數註冊爲GET請求的處理程序。函數
#!/usr/bin/env python from flask import Flask,render_template,session,redirect,url_for app = Flask(__name__) @app.route('/',methods=['GET','POST']) def index(): form = NameForm() if form.validate_on_submit(): session['name'] = form.name.data return redirect(url_for('index')) return render_template('index.html',form=form,name=session.get('name'))
例子:提示用戶名或密碼錯誤,彈出窗口
from flask import Flask,render_template,session,redirect,url_for,flash app = Flask(__name__) @app.route('/',methods=['GET','POST']) def index(): form = NameForm() if form.validata_on_submit(): old_name = session.get('name') if old_name is not None and old_name != form.name.data: flash('Looks like you have changed your name!') session['name'] = form.name.data return redirect(url_for('index')) return render_template('index.html',form=form,name=session.get('name'))
#渲染Flash消息 {% block content %} <div class="container"> {% for message in get_flashed_messages() %} <div class="alert alert-warning"> <button type="button" class="close" data-dismiss="alert">×</button> {{ message }} </div> {% endfor %} {% block page_content %}{% endblock %} </div> {% endblock %}