1、创建表单
使用 Flask-WTF 时,每个 Web 表单都由一个继承自 Form 的类表示。这个类定义表单中的一组字段,每个字 段都用对象表示。字段对象可附属一个或多个验证函数。验证函数用来验证用户提交的输入值是否符合要求。
【hello.py】
from flask_wtf
import FlaskForm
from wtforms
import SubmitField,StringField
from wtforms.validators
import DataRequired,Length
class NameForm(Form):
name = StringField(
'Input your name:',validators=[DataRequired()])
submit = SubmitField(
'Submit')
这个表单中的字段都定义为类变量,类变量的值是相应字段类型的对象。在这个示例中,NameForm 表单中有 一个名为 name 的文本字段和一个名为 submit 的提交按钮。 StringField类表示属性为 type=”text” 的 元素。 SubmitField 类表示属性为 type=”submit” 的 元素。字段构造函数的第一个参数是 把表单渲染成 HTML 时使用的标号。
StringField 构造函数中的可选参数 validators 指定一个由验证函数组成的列表,在接受用户提交的数据之 前验证数据。验证函数 Required() 确保提交的字段不为空。
2、把表单渲染成HTML
{% extends "base.html" %}
#继承基类
{% import "bootstrap/wtf.html" as wtf %}
导入wtf.quick_form用来快速生成表单
{% 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 %}
import 指令的使用方法和普通 Python 代码一样,允许导入模板中的元素并用在多个模板中。导入的 bootstrap/wtf.html 文件中定义了一个使用 Bootstrap 渲染 Falsk-WTF 表单对象的辅助函数。
wtf.quick_form() 函数的参数为 Flask-WTF 表单对象,使用 Bootstrap 的默认样式渲染传入的表单。
3、视图函数中处理表单 (V)
【views.html】
@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)
第一部分是页面头部,显示欢迎消息。这里用到了一个模板条件语句。 Jinja2 中的条件语句格式为 {% if condition %}…{% else %}…{% endif %}。
如果条件的计算结果为 True,那么渲染 if 和 else 指令之间的值。如果条件的计算结果为False,则渲染 else 和 endif 指令之间的值。在这个例子中,如果没有定义模板变量 name,则会渲染字符串“Hello, Stranger!”。内容区的第二部分使用 wtf.quick_form() 函数渲染NameForm 对象。
4、重定向与用户会话
为什么要重定向会话呢?因为当用户提交的时候表单method是POST,POST会成为 浏览器最后的一个请求,当刷新的时候,POST会导致刷新的时候再次提交。所以,要进行 重定向,使其成为GET。Post/ 重定向 /Get 模式。
【views.html】( v )
from flask
import session
@app.route('/form2/',methods = ['GET','POST'])
def form2():
form = NameForm()
if form.validate_on_submit():
session[
'name'] = form.name.data
return redirect(url_for(
'hello'))
return render_template(
'form.html',form = form, name = session.get(
'name'))
局部变量 name 用来存放表单中输入的有效名字,如果没有输入,其值为 None。如上述代码所示,在视图函 数中创建一个 NameForm 类实例用于表示表单。提交表单后,如果数据能被所有验证函数接受, 那么 validate_on_submit() 方法的返回值为 True,否则返回 False。这个函数的返回值决定是重新渲染表单还是 处理表单提交的数据。
5、Flash消息
让用户知道状态发生了变化
【views.html】
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() 函数,在发给客户端的下一个响应中显示一 个消息
在基模板里添加
【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 %}
在模板中使用循环是因为在之前的请求循环中每次调用 flash() 函数时都会生成一个消息,所以可能有多个 消息在排队等待显示。 get_flashed_messages() 函数获取的消息在下次调用时不会再次返回,因此 Flash消息只显示一次,然后就消失了。