Flask-WTF
保护表单免受跨站请求伪造(CSRF),通过设置密钥的方式
app.config['SECRET_KEY'] = 'hard to guess string'
表单类
字段对象可附属一个或者多个验证函数(用来验证用户体提交输入的值是否符合要求)
class NameForm(FlaskForm):
name = StringField('What is your name?', validators=[Required()])
submit = SubmitField('Submit')
表单中有name文本字段和submit提交按钮。
StringField类type="text"(注文本框),type = "submit"(提交按钮),构造函数中可选参数validators指定验证函数组成列表(Required()保证提交字段不为空)
视图函数
@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)
#POST为表单请求,GET请求将查询的字符串赋到URL中,不能用作提交表单
#validate_on_submit()如果GET返回False,POST返回True
模板
<form method="post">
{{ form.hidden_tag() }}
{{ form.name.label }}{{ form.name() }}
{{ form.submit()}}
</form>
Flask-Bootstrap提供的Flask-WTF表单
只需要该模板为
{% import "bootstrap/wtf.html" as wtf %}
{{ wtf.quick_form(form) }}
效果图
表4-1 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 内建的验证函数如表4-2 所示。
表4-2 WTForms验证函数
验证函数 说 明
Email 验证电子邮件地址
EqualTo 比较两个字段的值;常用于要求输入两次密码进行确认的情况
IPAddress 验证IPv4 网络地址
Length 验证输入字符串的长度
NumberRange 验证输入的值在数字范围内
Optional 无输入值时跳过其他验证函数
Required 确保字段中有数据
Regexp 使用正则表达式验证输入值
URL 验证URL
AnyOf 确保输入值在可选值列表中
NoneOf 确保输入值不在可选值列表中
参考文章:https://www.cnblogs.com/halleluyah/p/9015993.html
重定向
- 主要作为POST请求的响应
- 防止登录刷新再次提交POST,应跳转到登录界面重新输入要提交的POST消息
用户会话:默认保存在用户的cookie中,这里使用session
@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'))
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'))
在模板中接受传来的flask消息
用for循环从get_flashed_messages()中一一获取结果,视图函数flash()的值
{% 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 %}