Flask-WTF 及其依賴可以使用 pip 安裝:html
(venv) $ pip install flask-wtf
【設置密鑰】flask
app = Flask(__name__) app.config['SECRET_KEY'] = 'hard to guess string'
app.config 字典可用來存儲框架、 擴展和程序自己的配置變量。bootstrap
建立表單的三個步驟:瀏覽器
定義Form的子類服務器
在類裏添加字段session
在字段裏添加驗證函數app
# Form 基類由 Flask-WTF 擴展定義 from flask_wtf import FlaskForm # 字段直接從 WTForms 包中導入 from wtforms import StringField,SubmitField # 驗證函數直接從 WTForms 包中導入 from wtforms.validators import DataRequired,Length class NameForm(Form): name = StringField('Input your name:',validators=[DataRequired()]) submit = SubmitField('Submit')
與其餘擴展的使用方法不一樣之處在於:
①不是實例化,而是繼承
②還須要從wtforms當中導入字段和驗證函數框架
【注意】
Form 基類由 Flask-WTF 擴展定義,因此從 flask_wtf 中導入。字段和驗證函數
卻能夠直接從 WTForms 包中導入。函數
表單字段是可調用的,在模板中調用後會渲染成 HTML。假設視圖函數把一個
NameForm 實例經過參數 form傳入模板,在模板中能夠生成一個簡單的表單,
以下所示:ui
<form method="POST"> {{ form.hidden_tag() }} {{ form.name.label }} {{ form.name() }} {{ form.submit() }} </form>
可使用Bootstrap 中預先定義好的表單樣式渲染整個 Flask-WTF 表單,
使用 Flask-Bootstrap,上述表單可以使用下面的方式渲染:
{% import "bootstrap/wtf.html" as wtf %} {{ wtf.quick_form(form) }}
具體渲染方式以下:
【form.html】
{% 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 %}
模板的內容區如今有兩部分。第一部分是頁面頭部,顯示歡迎消息。這裏用到了一個
模板條件語句。 Jinja2中的條件語句格式爲 {% if condition %}...{% else %}...{% endif %}。
若是條件的計算結果爲 True,那麼渲染 if 和 else 指令之間的值。若是條件的計算結果爲False,
則渲染else 和 endif 指令之間的值。在這個例子中,若是沒有定義模板變量 name,則會渲染字
符串「Hello,Stranger!」。內容區的第二部分使用 wtf.quick_form() 函數渲染NameForm 對象。
視圖函數 index() 不只要渲染表單,還要接收表單中的數據。
@app.route('/form/',methods = ['GET','POST']) def form(): name = None form = NameForm() if form.validate_on_submit(): name = form.name.data form.name.data = '' return render_template('form.html',form = form, name = name)
上面的視圖函數存在一個可用性問題。用戶輸入名字後提交表單,而後點擊瀏覽器 的刷新按鈕,會看到一個莫名其妙的警告,要求在再次提交表單以前進行確認: 之因此出現這種狀況,是由於刷新頁面時瀏覽器會從新發送以前已經發送過的最後 一個請求。若是這個請求是一個包含表單數據的 POST 請求,刷新頁面後會再次提 交表單。大多數狀況下,這並非理想的處理方式。不少用戶都不理解瀏覽器發出 的這個警告。基於這個緣由, 最好別讓 Web 程序把 POST 請求做爲瀏覽器發送的 最後一個請求。 這種需求的實現方式是, 使用**重定向**做爲 POST 請求的響應,而不是使用常規 響應。這個技巧稱爲 Post/ 重定向 /Get 模式。 程序能夠把數據存儲在** 用戶會話 **中,在請求之間「記住」數據。用戶會話是一 種私有存儲,存在於每一個鏈接服務器的客戶端中。 咱們在請求與響應中介紹過用戶 會話,它是請求上下文中的變量,名爲 ** session **,像標準的 Python 字典一 樣操做。
from flask import session @app.route('/form2/',methods = ['GET','POST']) def form2(): form = NameForm() if form.validate_on_submit(): session['name'] = form.name.data # 這裏也不須要設置form.name.data = '', # 由於已經重定向到別的url去了,下次再到這個界面會自動初始化爲'' return redirect(url_for('hello')) return render_template('form.html',form = form, name = session.get('name'))
請求完成後,有時須要讓用戶知道狀態發生了變化。這裏可使用確認消息、警告或者 錯誤提醒。一個典型例子是,用戶提交了有一項錯誤的登陸表單後,服務器發回的響應 從新渲染了登陸表單,並在表單上面顯示一個消息,提示用戶用戶名或密碼錯誤。 經過Flask 的核心特性,** flash()函數 **可實現這種效果
from flask import flash @app.route('/form3/',methods = ['GET','POST']) def form3(): form = NameForm() if form.validate_on_submit(): old_name = session.get('name') if old_name is not None and old_name != form.name.data : flash('you have changed your name') session['name'] = form.name.data return redirect(url_for('hello')) return render_template('form.html',form = form, name = session.get('name'))
僅調用 flash() 函數並不能把消息顯示出來,程序使用的模板要渲染這些消息。 最好在基模板中渲染 Flash消息,由於這樣全部頁面都能使用這些消息。 Flask 把 get_flashed_messages() 函數開放給模板,用來獲取並渲染消息。
【base.html】
{% 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 %}
在這個示例中,使用 Bootstrap 提供的警報 CSS 樣式渲染警告消息。
【注意】 在模板中使用循環是由於在以前的請求循環中每次調用 flash() 函數時都會生成一個消息,因此可能有多個消息在排隊等待顯示。 get_flashed_messages() 函數獲取的消息在下次調用時不會再次返回,所以 Flash消息只顯示一次,而後就消失了。