尽管 Flask 的请求对象提供的信息足以处理 Web 表单,但有些任务很单调,而且要重复操作。比如,生成表单的 HTML 代码和验证提交的表单数据。Flask-WTF 扩展可以把处理 Web 表单的过程简化了,这个扩展对独立的 WTForms 包进行了包装,方便集成到 Flask 应用中。

配置

Flask-WTF 无须在应用层初始化,但是它要求应用配置一个密钥,Flask 使用这个密钥保护用户会话,防止表单遭到跨站请求伪造(CSRF)攻击。

app.config['SECRET_KEY'] = 'hard to guess string'

定义表单

使用 Flask-WTF 时,在服务器端,每个 Web 表单都由一个继承自 FlaskForm 的类表示。这个类定义表单中的一组字段,每个字段都用对象表示。字段对象可附属一个或多个验证函数。验证函数用于验证用户提交的数据是否有效

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired class NameForm(FlaskForm):
name = StringField('What is your name?', validators=[DataRequired()])
submit = SubmitField('Submit')

Field:https://wtforms.readthedocs.io/en/2.3.x/fields/#basic-fields

validators:https://wtforms.readthedocs.io/en/2.3.x/validators/#module-wtforms.validators

渲染表单

视图函数通过 form 参数把一个 NameForm 实例传入模板,在模板中可以生成一个简单的 HTML 表单。还可以为字段指定 idclass 属性,然后为其定义 CSS 样式:

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

使用Flask-Bootstrap渲染

Flask-Bootstrap 扩展提供了一个高层级的辅助函数,可以使用 Bootstrap 预定义的表单样式渲染整个 Flask-WTF 表单。

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

处理表单数据

用户提交表单后,服务器会收到一个的 POST 请求。如果能通过验证,validate_on_submit() 返回 True,用户输入的名字可通过字段的 data 属性获取:

@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请求后,如果刷新页面,会弹出警告。这是因为刷新页面时浏览器会重新发送之前发送过的请求。如果前一个请求是包含表单数据的 POST 请求,刷新页面后会再次提交表单,所以浏览器弹出警告,让用户确认。

鉴于此,最好使用重定向作为POST请求的响应,这样上一个请求就永远是GET。这样的话又产生另一个问题,即重定向的响应无法传入数据,这样就需要使用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'))

默认情况下,session 保存在客户端 cookie 中,使用前面设置的密钥加密签名。如果篡改了 cookie 的内容,签名就会失效,会话也将随之失效。

消息闪现

请求完成后,有时需要让用户知道状态发生了变化,可以是确认消息、警告或者错误提醒。Flask 本身内置消息闪现功能,使用方法如下:

① 视图函数中调用flash函数

视图函数:
...
flash('登陆成功!')
return ...

② 模板中渲染消息:最好在基模版中渲染闪现消息,这样所有页面都可以调用

{% for message in get_flashed_messages() %}

<div class="alert alert-warning">
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ message }}
</div> {% endfor %}

这个示例使用 Bootstrap 提供的 CSS alert 样式渲染警告消息,其他样式可参考相关API文档。

Flask:处理Web表单的更多相关文章

  1. Flask教程 —— Web表单(上)

    第二章中介绍的request对象公开了所有客户端发送的请求信息.特别是request.form可以访问POST请求提交的表单数据. 尽管Flask的request对象提供的支持足以处理web表单,但依 ...

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

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

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

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

  4. Flask学习 三 web表单

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

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

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

  6. Flask之模板web表单

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

  7. Flask:web表单

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

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

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

  9. Flask开发系列之Web表单

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

  10. Flask学习之三 web表单

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

随机推荐

  1. UVA 10294 项链与手镯 (置换)

    Burnside引理:对于一个置换\(f\), 若一个着色方案\(s\)经过置换后不变,称\(s\)为\(f\)的不动点.将\(f\)的不动点数目记为\(C(f)\), 则可以证明等价类数目为\(C( ...

  2. AcWing 241 楼兰图腾 (树状数组)

    在完成了分配任务之后,西部314来到了楼兰古城的西部. 相传很久以前这片土地上(比楼兰古城还早)生活着两个部落,一个部落崇拜尖刀('V'),一个部落崇拜铁锹('∧'),他们分别用V和∧的形状来代表各自 ...

  3. hdu 6832 A Very Easy Graph Problem 构造树+dfs

    题意: 给你一个n个点m条边的图,对于第i条边,它的长度是2i,对于每一个顶点,它不是0类型,就是1类型.你需要找出来对于所有的"两个不同类型的点之间最短距离"的和 题解(参考:h ...

  4. Codeforces Round #614 (Div. 1) A. NEKO's Maze Game (思维,模拟)

    题意:有一个\(2\)X\(n\)的矩阵,你想从\((1,1)\)走到\((2,n)\),每次可以向上下左右四个方向走,但在某些时间段某个点会被堵住,如果已经被堵住,那么即恢复正常,每次对某个点操作, ...

  5. c++派生类中构造函数和析构函数执行顺序、判断对象类型、抽象类、虚函数

    一. 代码: 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include&l ...

  6. Linux入门详解

    Linux基础知识 Linux&Unix 说起Linux,就不得不提Unix操作系统. Unix系统号称世界上最稳定的系统,就连苹果公司也从中获取灵感开发出了移动端大名鼎鼎的IOS. Unix ...

  7. spark 一、编程指南

    总览 第一.每个spark 应用都有一个驱动程序去运行着主函数和再每个节点上的并行操作. spark提供了一个RDD(弹性分布式数据集)的数据集合,可以通过不同的节点并行操作运算,可以通过hdfs文件 ...

  8. python之字符串方法upper/lower

    1.描述: upper():用于将字符串全部转换为大写字母 lower():用于将字符串全部转换为小写字母 2.语法 str.upper() str.lower() 3.返回值 upper()或low ...

  9. mybatis(八)手写简易版mybatis

    一.画出流程图 二.设计核心类 二.V1.0 的实现 创建一个全新的 maven 工程,命名为 mebatis,引入 mysql 的依赖. <dependency> <groupId ...

  10. js Array.from & Array.of All In One

    js Array.from & Array.of All In One 数组生成器 Array.from The Array.from() static method creates a ne ...