Flask-WTF插件可以把处理 Web 表单的过程变成一种愉悦的体验。
- 安装:
(venv) $ pip install flask-wtf
- 用法:
app.config['SECRET_KEY'] = 'hard to guess string' #实现 CSRF 保护,Flask-WTF 使用这个密钥生成加密令牌,再用令牌验证请求中表单数据的真伪
hello.py:定义表单类
from flask.ext.wtf import Form
from wtforms import StringField, SubmitField
from wtforms.validators import Required
class NameForm(Form):
name = StringField('What is your name?', validators=[Required()]) #可选参数 validators 指定一个由验证函数组成的列表,在接受
用户提交的数据之前验证数据。
submit = SubmitField('Submit')
处理表单:
- 渲染表单:
{% import "bootstrap/wtf.html" as wtf %}
{{ wtf.quick_form(form) }}
导入的 bootstrap/wtf.html 文件中定义了一个使用 Bootstrap 渲染 Falsk-WTF 表单对象的辅助函数,只需一次调用即可完成。 wtf.quick_form() 函数的参数为 Flask-WTF 表单对象,使用 Bootstrap 的默认样式渲染传入的表单。
- 视图函数处理表单:
路由方法
@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)
创建一个 NameForm 类实例用于表示表单。
提交表单后,如果数据能被所有验证函数接受,那么 validate_on_submit() 方法的返回值为 True ,否则返回 False 。这个函数的返回值决定是重新渲染表单还是处理表单提交的数据。
重定向和用户会话:
很多情况提交表单后再次刷新,浏览器会发出警告,要求在再次提交表单之前进行确认。
为了别让 Web 程序把 POST 请求作为浏览器发送的最后一个请求,使用重定向作为 POST 请求的响应,而不是使用常规响应。最后一个请求是 GET 请求,所以刷新命令能像预期的那样正常使用了。这个技巧称为 Post/ 重定向 /Get 模式。
flask提供了redirect() 辅助函数用来生成 HTTP 重定向响应。
from flask import Flask, render_template, session, redirect, url_for
@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'))
局部变量 name 被用于存储用户在表单中输入的名字。这个变量现在保存在用户会话中,即 session[‘name’] ,所以在两次请求之间也能记住输入的值。
url_for() 函数的第一个且唯一必须指定的参数是端点名,即路由的内部名字。默认情况下,路由的端点是相应视图函数的名字。在这个示例中,处理根地址的视图函数是index() ,因此传给 url_for() 函数的名字是 index 。
当用户访问某些网页时,如果他还没登录,我们往往会把网页重定向到登录页面,
如果用户注册了,我们将网页重定向到首页。
Flash消息:
flask提供了flash()函数
用户在程序上的使用过程,web程序可以在页面上显示消息提示用户的状态变化, 例如确认消息、警告或者错误提醒。
from flask import Flask, render_template, session, redirect, url_for, flash
@app.route('/', methods=['GET', 'POST'])
def index():
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('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() 函数并不能把消息显示出来,程序使用的模板要渲染这些消息。最好在基模板中渲染 Flash 消息,因为这样所有页面都能使用这些消息。Flask 把 get_flashed_messages() 函数开放给模板,用来获取并渲染消息。
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
在模板中使用循环是因为在之前的请求循环中每次调用 flash() 函数时都会生成一个消息,所以可能有多个消息在排队等待显示。 get_flashed_messages() 函数获取的消息在下次调用时不会再次返回,因此 Flash 消息只显示一次,然后就消失了