处理Web表单的扩展 Flask-WTF
Flask-wtf 对WTForms包进行了包装,方便集成入Flask框架
跨站请求保护
CSRF(Cross-Site Request Forgery)是指恶意网站把请求发送到被攻击者已登录的其他网站就会引发CSRF攻击
为了实现CSRF保护,需要程序设置密钥,生成加密令牌,再用来验证表单数据真伪。非常简单:
app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'
不过在生产环境,不会直接写入程序,而会从文件或环境中导入配置值,Flask-wtf提供了方法来实现
表单类
使用Flask-wtf时,每一个表单都由一个继承自Form类表示,这个类定义表单的字段,每个字段由对象表示,
字段对象可以附属一个或多个验证函数,验证函数负责验证用户提交输入值是否符合要求
示范:
from flask.ext.wtf import Form
from wtforms import StringField,SubmitField
from wtforms.validators import DataRequired,Email
class NameForm(Form):
name = StringField('what is your name ?',validators=[DataRequired()])
email = StringField('what is your email ?',validators=[Email()])
submit = SubmitField('Submit')
上面代码定义了3个字段:name,email,submit三个字段,name和email表示"text" 的input元素,
submit表示type = 'submit'的“input”元素。DataRequired接受用户输入之后,确保提交字段不为空,
Email确保输入为符合邮件的函数
WTForms支持的HTML标准字段 举例,更多可以查官方文档
字段类型
说明
StringField
文本字段
TextAreaField
多行文本字段
PasswordField
密码文本字段
HiddenField
隐藏文本字段
DateField
文本字段,值为datetime.date格式
DateTimeField
文本字段,值为datetime.datetime格式
IntegerField
文本字段,值为整数
DecimalField
文本字段,值为decimal.Decimal
FloatField
文本字段,值为浮点数
BooleanField
复选框,值为True和False
RadioField
一组单选框
SelectField
下拉列表
SelectMultipleField
下拉列表,可以选多个值
FileField
文件上传字段
SubmitField
表单提交按钮
FormField
把表单作为字段嵌入另一个表单
FieldList
一组指定类型字段
WTForms内建验证函数
验证函数
说明
验证邮件地址
EqualTo
比较2个字段值,一般用于输入2次密码进行确认情况
IPAddress
验证IPV4地址
Length
验证输入字符长度
Optional
无输入值时跳过其他验证函数
Required
确保字段有值
Regxp
使用正则表达式验证输入值
URL
验证URL
AnyOf
确保输入值在可选值列表中
NoneOf
确保输入值不在可选值列表
表单渲染成HTML
Flask-Bootstrap提供了一个辅助函数,使用Bootstrap预先定义好的表单样式渲染Flask-Wtf表单对象,使用Bootstrap默认样式渲染传入的表单。
还可以使视图函数渲染表单,接收表单数据
py:
@app.route('/',methods=['GET','POST'])
def index():
name = None
email = None
form = NameForm()
if form.validate_on_submit():
name = form.name.data
email = form.email.data
form.name.data = ''
form.email.data = ''
return render_template('index.html',form=form,name=name)
html:
Hello, {% if name %}{{ name }}{% else %}Stranger{% endif %}!
{{ wtf.quick_form(form) }}
重定向和用户会话
如果使用上面的视图函数,重复点击链接会再次提交表单,让你确认。
不过可以重定向POST请求,重新向重定向的URL发起GET请求,显示页面内容 - POST/重定向/GET,模式
不过,处理POST请求时,如果不保存数据,下次请求来时,数据就已经丢失。
不过,可以通过用户会话(session)保存数据,并且像python字典一样操作
默认情况下,用户会话保存在cookie中,而且cookie使用SECRET_KEY加密
示范代码:
@app.route('/',methods=['GET','POST'])
def index():
form = NameForm()
if form.validate_on_submit():
session['name'] = form.name.data
session['email'] = form.email.data
return redirect(url_for('index')) # url_for重定向必须是相应视图函数的名字
return render_template('index.html',form=form,name=session.get('name'),email=session.get('email'))
Flash消息
如果状态发生变化,可以通过flash()通知用户 -确认消息,警告或者错误提醒 FLask的核心特性
不过仅仅调用flash()不能把消息显示,还需要模板渲染消息,最好在基模板渲染,这样所有页面都能使用。
py:
@app.route('/',methods=['GET','POST'])
def index():
form = NameForm()
if form.validate_on_submit():
oldname = session['name']
if oldname is not None and oldname!=form.name.data:
flash('Looks like you have changed your name!')
old_email = session['email']
if old_email is not None and old_email !=form.email.data:
flash('Email changed!')
session['name'] = form.name.data
session['email'] = form.email.data
return redirect(url_for('index')) # url_for重定向必须是相应视图函数的名字
return render_template('index.html',form=form,name=session.get('name'),email=session.get('email'))
html:
{% for msg in get_flashed_messages() %}
×
{{ msg }}
{% endfor %}