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消息只显示一次,而后就消失了。