title: 利用pycharm学习flask(八)
date: 2016-10-04 15:36:58
tags: python
category: python
本文内容:
1.跨站请求伪造保护
2.表单类
3.把表单渲染成HTML
4.在视图函数中处理表单
跨站请求伪造保护
Flask-WTF是一个扩展,可以帮助我们处理web表单,我们跟前面一样在pycharm中安装它。
默认情况下,Flask-WTF能保护所有表单免受跨站请求伪造的攻击。Flask-WTF需要程序设置一个密匙。Flask-WTF使用这个密匙生成加密令牌,再用令牌验证请求中表单数据的真伪。
修改hello.py:
app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'
其中app.config字典用来存储框架、扩展和程序本身的配置变量。使用标准的字典句法就能把配置值添加到app.config对象中。
表单类
使用Flask-WTF时,每个Web表单都由一个继承自Form的类表示。这个类定义表单中的一组字段,每个字段都用对象表示。字段对象可附属一个或多个验证函数。验证函数用来验证用户提交的输入值是否符合要求。
修改hello.py,定义表单类:
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import Required
class NameForm(FlaskForm):
name = StringField('What is your name?',validators=[Required()])
submit = SubmitField('Submit')
这个表单中的字段都定义为类变量,类变量的值是相应字段类型的对象。NameForm表单中有一个名为name的文本字段和一个名为submit的提交按钮。StringField类表示属性为type=“text”的input元素。SubmitField类表示属性为type="submit"的input元素。
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 | 比较两个字段的值;常用于要求输入两次密码进行确认的情况 |
IPAddress | 验证 IPv4 网络地址 |
Length | 验证输入字符串的长度 |
NumberRange | 验证输入的值在数字范围内 |
Optional | 无输入值时跳过其他验证函数 |
Required | 确保字段中有数据 |
Regexp | 使用正则表达式验证输入值 |
URL | 验证 URL |
AnyOf | 确保输入值在可选值列表中 |
NoneOf | 确保输入值不在可选值列表中 |
把表单渲染成HTML
Flask-Bootstrap 提供了一个非常高端的辅助函数,可以使用Bootstrap中预先定义好的表单样式渲染整个 Flask-WTF表单,而这些操作只需一次调用即可完成。使用Flask-Bootstrap,上述表单可使用下面的方式渲染:
{% import "bootstrap/wtf.html" as wtf %}
{{ wtf.quick_form(form) }}
import指令的使用方法和普通Python代码一样,允许导入模板中的元素并用在多个模板中。导入的bootstrap/wtf.html文件中定义了一个使用Bootstrap渲染 Falsk-WTF表单对象的辅助函数。wtf.quick_form() 函数的参数为Flask-WTF表单对象,使用Bootstrap的默认样式渲染传入的表单。
修改templates/index.html,使用Flask-WTF和Flask-Bootstrap渲染表单:
{% 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不仅要渲染表单,还要接收表单中的数据,修改hello.py如下:
@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',from=from,name=name)
其中app.route修饰器中添加的methods参数告诉flask在url映射中把这个视图函数注册为GET和POST请求的处理程序,如果没有这个参数,默认为GET请求。
局部变量name存储表单中的名字,如果没有输入就为NONE,创建了一个NameForm类实例用于表示表单。提交表单后,如果数据能被所有验证函数接受,那么validate_on_submit方法返回True,否则返回False。这个值决定是重新渲染表单还是处理表单提交的数据。
第一次访问时,服务器收到一个没有表单数据的GET请求,所以validate_on_submit返回False。if语句将被跳过,通过渲染模板处理请求,并传入表单对象和值为None的name变量作为参数。用户在浏览器中显示了一个表单。
提交表单后,服务器收到GET请求,validate_on_submit调用name字段上的Required验证函数。如果名字不为空,就通过。validate_on_submit返回True。用户输入的名字可以通过字段的data属性获取。
在if语句中,把名字复制给name,然后再把data属性设为空字符串,从而清空表单字段。最后一行调用render_template函数渲染模板,但这次参数name的值为表单中输入的名字,因此会显示一个针对该用户的欢迎消息。