第二章中介绍的request对象公开了所有客户端发送的请求信息。特别是request.form可以访问POST请求提交的表单数据。

尽管Flask的request对象提供的支持足以处理web表单,但依然有许多任务会变得单调且重复。表单的HTML代码生成和验证提交的表单数据就是两个很好的例子。

Flask-WTF扩展使得处理web表单能获得更愉快的体验。该扩展是一个封装了与框架无关的WTForms包的Flask集成。

Flask-WTF和它的依赖集可以通过pip来安装:

(venv) $ pip install flask-wtf

1、跨站请求伪造(CSRF)保护

默认情况下,Flask-WTF保护各种形式对跨站请求伪造(CSRF)攻击。一个CSRF攻击发生在一个恶意网站发送请求给受害者登录的其他网站。

为了实现CSRF保护,Flask-WTF需要应用程序去配置一个加密密钥。Flask-WTF使用这个密钥去生成加密令牌用于验证请求表单数据的真实性。示例4-1展示如何配置加密密钥。

示例4-1. hello.py:Flask-WTF配置

app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'

app.config字典通常是框架、扩展或应用程序自身存放配置变量的地方,可以使用标准字典语法添加配置值到app.config中。配置对象提供方法来从文件或环境导入配置值。

SECRET_KEY配置变量作为Flask和一些第三方扩展的通用加密密钥。加密的强度取决于这个变量的值。给你构建的每个应用程序选择不同的密钥,并确保这个字符串不被其他任何人知道。

注:为了提高安全性,密钥应该存储在一个环境变量中,而不是嵌入到代码中。这个会在第7章中描述。

2、表单类

使用Flask-WTF时,每个web表单是由继承自Form类的子类来展现的。该类在表单中定义了一组表单域,每个都表示为一个对象。每个表单域都可以连接到一个或多个validatorsvalidators是一个用于检查用户提交的输入是否合法的函数。

示例4-2展示了一个拥有文本框和提交按钮的简单web表单。

示例4-2. hello.py:表单类定义

from flask.ext.wtf import Form
from wtforms import StringField, SubmitField
from wtforms.validators import Required class NameForm(Form):
name = StringField('What is your name?', validators=[Required()])
submit = SubmitField('Submit')

表单中的域被定义为类的变量,且每个类的变量都指定一个表单域类型对象。在上一个示例中,NameForm表单有一个name文本框和submit提交按钮。StringField类表示一个type="text"属性的<input>标签。SubmitField类表示一个type="submit"属性的<input>标签。表单域构造函数的第一个参数是一个label,在渲染表单到HTML时会使用。

StringField构造函数包含可选参数validators,它定义了一组检查来验证用户提交的数据。Required()验证确保提交的表单域不为空。

注:Flask-WTF扩展定义了表单基类,所以它从flask.ext.wtf导入。表单域、验证都是直接从WTForms包中导入。

表格4-1展示了一组WTForms支持的标准表单域。

表格4-1. WTForms标准HTML表单域

表格4-2展示了一组WTForms内建验证。

表格4-2. WTForms验证

3、HTML渲染的表单

表单域是可调用的,调用时从模板渲染它们到HTML。假设视图函数传递一个参数名为formNameForm实例给模板,模板就会生成一个简单的HTML表单,如下所示:

<form method="POST">
{ { form.name.label }} { { form.name() }}
{ { form.submit() }}
</form>

当然,结果是什么都没有。为了改变表单的外观显示,任何发送给该表单域的参数会被转换为HTML表单域属性;例如,你可以给定表单域idclass属性,然后定义CSS样式:

<form method="POST">
{ { form.name.label }} { { form.name(id='my-text-field') }}
{ { form.submit() }}
</form>

即使有HTML属性,努力用这种方式渲染表单是非常重要的,所以最好是尽可能的使用Bootstrap自带的一系列表单样式。Flask-Bootstrap使用Bootstrap的预定义表单样式来提供高级的帮助函数来渲染整个Flask-WTF表单,这些操作都只需要一个调用即可完成。使用Flask-Bootstrap,上一个表单可以像下面这样来渲染:

{ % import "bootstrap/wtf.html" as wtf %}
{ { wtf.quick_form(form) }}

import指令和常规的Python脚本一样的作用并且允许模板元素被导入并在许多模板中使用。被导入的bootstrap/wtf.html文件,定义了帮助函数使用Bootstrap来渲染Flask-WTF表单。wtf.quick_form()函数传入Flask-WTF表单对象并使用默认Bootstrap样式渲染它。示例4-3展示了完整的hello.py模板。

示例4-3. 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 %}

目前模板的内容区有两块。第一块是类为page-header的div输出一个问候语。这里使用了模板条件判断语句。在Jinja2中格式为{ % if variable %}...{ % else %}...{ % endif %}。如果判断条件为True则渲染ifelse之间的内容。如果判断条件为False则渲染elseendif之间的内容。示例模板会渲染字符串“Hello, Stranger!”当name模板参数未定义的时候。第二块内容使用wtf.quick_form()函数渲染NameForm对象。

转自:Flask教程 —— Web表单(上)

相关阅读(python及flask)

Flask教程 —— Web表单(上)的更多相关文章

  1. Python——Flask框架——Web表单

    一.框架Flask-WTF 安装: pip install flask-wtf 需要程序设置一个密钥 app = Flask(__name__) app.config['SECRET_KEY'] = ...

  2. Flask Web Development —— Web表单(上)

    Flask-WTF扩展使得处理web表单能获得更愉快的体验.该扩展是一个封装了与框架无关的WTForms包的Flask集成. Flask-WTF和它的依赖集可以通过pip来安装: (venv) $ p ...

  3. Flask 教程 第三章:Web表单

    本文翻译自 The Flask Mega-Tutorial Part III: Web Forms 这是Flask Mega-Tutorial系列的第三部分,我将告诉你如何使用Web表单. 在第二章中 ...

  4. Flask学习之三 web表单

    本部分Miguel Grinberg教程的翻译地址:http://www.pythondoc.com/flask-mega-tutorial/webforms.html 开源中国的:http://ww ...

  5. Flask学习 三 web表单

    web表单 pip install flask-wtf 实现csrf保护 app.config['SECRET_KEY']='hard to guess string' # 可以用来存储框架,扩展,程 ...

  6. flask 利用flask_wtf扩展 创建web表单

    在Flask中,为了处理web表单,我们一般使用Flask-WTF扩展,它封装了WTForms,并且它有验证表单数据的功能 创建语句格式: startTime = DateTimeField('计划开 ...

  7. Flask之模板web表单

    3.3 Web表单: web表单是web应用程序的基本功能. 它是HTML页面中负责数据采集的部件.表单有三个部分组成:表单标签.表单域.表单按钮.表单允许用户输入数据,负责HTML页面数据采集,通过 ...

  8. Flask:web表单

    客户端发送的所有通过POST发出的请求信息都可以通过request.form获取.但是如果我们要生成表单的HTML代码和验证提交的表单数据那么就需要采用另外的方法.Flask-WTF扩展可以把处理we ...

  9. Flask开发系列之Web表单

    Flask开发系列之Web表单 简单示例 from flask import Flask, request, render_template app = Flask(__name__) @app.ro ...

随机推荐

  1. JavaScript 之 parseInt

    首先还是从很热门的实例parseInt("09")==0说起. parseInt(numString, [radix])这个函数后面如果不跟第2个参数来表示进制的话,默认是10进制 ...

  2. MVC模式下值的传递

    公司项目转用MVC开发,故学习总结一下mvc会用到的常用传值方法:       正如大家都熟悉的,MVC路由及运行机制是:       首先,Web 浏览器向服务器发送一条URL 请求,如http:/ ...

  3. 【CMS】DedeCMS Error: (PHP 5.3 and above) Please set 'request_order' ini value to include C,G and P (recommended: 'CGP') in php.ini

    DedeCMS Error: (PHP 5.3 and above) Please set 'request_order' ini value to include C,G and P (recomm ...

  4. 【Oracle】存储过程之完整篇

    1.语法 create [or replace] procedure pro_name[(parameter1,parameter2,...)] is|as begin plsql_sentences ...

  5. tracteroute路由追踪

    traceroute 跟踪数据包到达网络主机所经过的路由工具: 是用来发出数据包的主机到目标主机之间所经过的网关的工具.traceroute 的原理是试图以最小的TTL发出探测包来跟踪数据包到达目标主 ...

  6. Android API之java.lang.String

      boolean java.lang.String.contains(CharSequence cs) String字符串是否包含CharSequence(cs).

  7. Spring框架文档与API(4.3.6版本)

    http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/ Table of Contents I ...

  8. 深入PHP内核之opcode handler

    1.opcode结构 在Zend/zend_compile.h文件下 struct _zend_op { opcode_handler_t handler; znode_op op1; znode_o ...

  9. ios block常见的错误(二)——循环引用

    这篇博文继续block的常见错误——循环引用. 循环引用是很多初学者不能察觉的,其产生的原因,是block中的代码会对对象进行强引用. 读者请阅读示例代码1,并思考示例代码1所创建的对象能否被正常销毁 ...

  10. ORA-04089: 无法对 SYS 拥有的对象创建触发器

    ORA-04089: 无法对 SYS 拥有的对象创建触发器 http://bbs.csdn.net/topics/390355220 猛然发现自己是用sys用户创建表空间,创建用户,赋权,顺手就把sq ...