Python Flask Web 第十课 —— flask-wtf
2016-06-05 22:00
405 查看
1. Flask-WTF 的安装与密钥的设置
默认情况下,flask-wtf 能保护所有表单免受跨站请求伪造(Cross-site Request Forgery,CSRF)的攻击。恶意网站把请求发送到攻击者已登陆的其他网站时就会引发 CSRF 攻击。flask-wtf 的安装如下:
pip install flask-wtf
为了实现 CSRF 保护,Flask-WTF 需要程序设置一个密钥,Flask-WTF 使用这个密钥生成加密令牌,再用令牌验证请求中表单数据的真伪。
设置密钥的方法如下所示:
app.config['SECRET_KEY'] = 'hard to guess'
app.config 字典可用来存储框架、扩展和程序本身的配置变量。
2. 表单类
使用 flask-wtf 时,每个 Web 表单都由一个继承自 Form 的类表示。该类用于定义表单中的一组字段,每个字段都用对象表示。字段对象可附属一个或多个验证函数。验证函数用来验证用户提交的输入值是否符合要求。from flask_wtf import Form from wtforms import StringField, SubmitField from wtforms.validators import DataRequired class NameForm(Form): name = StringFiled('What is your name?', validators=[DataRequired()]) submit = SubmitField('submit')
StringFiled 类表示属性为 type=”text” 的 <input> 元素。
SubmitField 类表示属性为 type=”submit” 的 <input> 元素。
DataRequired()确保提交的字段不为空。
3. 把表单渲染成 HTML
tempaltes/base.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 %}
4. 在视图函数中处理表单
@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', name=name, form=form)
5. 重定向和用户会话
这里还存在一个可用性问题,就是用户输入名字后提交表单,然后点击浏览器的刷新按钮,会看到一个警告,要求在再次提交表单之前进行确认。之所以出现这种情况,是因为刷新页面时浏览器会重新发送之前已经发送过的最后一个请求。如果这个请求是一个包含表单数据的 POST 请求,刷新页面后会再次提交表单。当然,大部分情况下,这并非是最理想的处理方式。基于此,最好不让 POST 作为浏览器发送的最后一个请求。
该需求的实现方式为,使用重定向作为 POST 请求的响应,而不是常规响应,重定向是一种特殊的响应,响应内容是 URL,而不是包含 HTML 代码的字符串。浏览器收到这种响应时,会向重定向的 URL 发起 GET 请求,显示页面内容,这个页面的加载可能要花几微妙,因为要先把第二个请求发送给服务器。除此之外,对用户透明(用户不会觉察有什么不同)。如此,便实现了最后一个请求是 GET 请求,所以刷新命令能像预期的那样正常使用了。该技术称为 POST/ 重定向 GET/模式。
@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', name=session.get('name'), form=form)
6. 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('look like you have changed your name!') session['name'] = form.name.data return redirect(url_for('index')) return render_template('index.html', name=session.get('name'), form=form)
仅调用 flash() 函数并不能把消息显示出来,程序使用的模板要渲染这些消息。最好在基模板(templates/base.html)中渲染 flash 消息。这样所有页面均可使用这些消息。
{% block content %} <div class="container"> {% for message in get_flash_messages() %} <div classs="alert alert-warning"> <button type="button" class="close" data_dismiss="alert">×</button> {{message}} </div> {% endfor %} {% block page_content %}{% endblock %} </div> {% endblock %}
相关文章推荐
- python 用pdb调试
- python-os/sys/subprocess
- Python之路_Day5
- 关于 Python generator(生成器)的类比
- Python全栈开发
- 通过xpath读取xml节点
- XTEA加密的Python调用
- Windows环境下实现Numpy、Scipy、Matlotlib、Scikit-learn的安装
- 从Python中readline()函数读取的一行内容中去掉换行符\n
- pip安装失败
- 119. Pascal's Triangle II [easy] (Python)
- python爬虫解决验证码的思路
- python之列表、元祖、集合、字典基础篇
- python 的 subprocess模块用法 popen
- [python学习] 介绍python的property,以及为什么要用setter,一个小栗子
- Python之路【第一篇】:Python前世今生
- 第一次抢课经历
- python-开发之路-格式化输入
- Opencv3.0-python: 视频处理时报错color.cpp:7456: error: (-215) scn == 3 || scn == 4 的解决办法
- python wave文件的额处理方法