尽管 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. BZOJ1150 [CTSC2007]数据备份Backup 链表+小根堆

    BZOJ1150 [CTSC2007]数据备份Backup 题意: 给定一个长度为\(n\)的数组,要求选\(k\)个数且两两不相邻,问最小值是多少 题解: 做一个小根堆,把所有值放进去,当选择一个值 ...

  2. HDU6321 Dynamic Graph Matching【状压DP 子集枚举】

    HDU6321 Dynamic Graph Matching 题意: 给出\(N\)个点,一开始没有边,然后有\(M\)次操作,每次操作加一条无向边或者删一条已经存在的边,问每次操作后图中恰好匹配\( ...

  3. 牛客NC15879 A Simple Problem

    传送门:A Simple Problem 题意 给定两个序列s1和s2,同样的数字可以用相同的别的数字代替(并且也可以是出现过的数字),问s2在s1中出现了几次. 题解 首先预处理一下这两个序列,因为 ...

  4. 【洛谷 p3381】模板-最小费用最大流(图论)

    题目:给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 解法:在Dinic的基础下做spfa算法. 1 #include<cst ...

  5. P1251 餐巾计划 (网络流)

    题意:餐厅每天会需要用Ri块新的餐巾 用完后也会产生Ri块旧的餐巾 每天购买新的餐巾单价p元 每天产出的旧餐巾可以送到快洗部花费每张c1元 在i + v1天可以使用 也可以花费c2元每张送到慢洗部 在 ...

  6. 【2020杭电多校】Distinct Sub-palindromes 找规律

    题目链接:Distinct Sub-palindromes 题意: 给你一个长度n,你需要找出来一些串,这些串由A...Z和a...z构成.我们设长度为n的所有串中所包含回文子串最少的数量为ans.问 ...

  7. Codeforces Round #613 (Div. 2) C. Fadi and LCM (数学)

    题意:给你一个正整数\(x\),找两个正整数\(a\),\(b\),使得\(lcm(a,b)=x\),并且\(max(a,b)\)最小. 题解:我们知道,\(lcm(a,b)=a*b/gcd(a,b) ...

  8. Educational Codeforces Round 94 (Rated for Div. 2) C. Binary String Reconstruction (构造)

    题意:给你一个字符串\(s\),原字符串为\(w\),如果\(i>x\)且\(w_{i-x}=1\),那么\(s_{i}=1\),如果\(i+x\le n\)且\(w_{i+x}=1\),那么\ ...

  9. String常用方法介绍

    转载 int length(); 语法:字符串变量名.length(); 返回值为 int 类型.得到一个字符串的字符个数(中.英.空格.转义字符皆为字符,计入长度). String a=" ...

  10. 数据可视化 -- Python

    前提条件: 熟悉认知新的编程工具(jupyter notebook) 1.安装:采用pip的方式来安装Jupyter.输入安装命令pip install jupyter即可: 2.启动:安装完成后,我 ...