Flask表单详解

Flask表单详解

  • 概述
  • 跨站请求伪造保护
  • 表单类
  • 把表单渲染成HTML
  • 在视图函数中处理表单
  • 重定向和用户会话
  • Flash消息

概述

尽管 Flask 的请求对象提供的信息足够用于处理 Web 表单,但有些任务很单调,而且要重复操作。比如,生成表单的 HTML 代码和验证提交的表单数据
Flask-WTF(http://pythonhosted.org/Flask-WTF/)扩展可以把处理 Web 表单的过程变成一种愉悦的体验。这个扩展对独立的 WTForms(http://wtforms.simplecodes.com)包进行了包装,方便集成到 Flask 程序中
Flask-WTF 及其依赖可使用 pip 安装:

pip install flask-wtf

跨站请求伪造保护

默认情况下,Flask-WTF 能保护所有表单免受跨站请求伪造(CSRF)的攻击
为了实现 CSRF 保护,Flask-WTF 需要程序设置一个密钥。Flask-WTF 使用这个密钥生成加密令牌,再用令牌验证请求中表单数据的真伪

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

表单类

使用 Flask-WTF 时,每个 Web 表单都由一个继承自 Form 的类表示。这个类定义表单中的一组字段,每个字段都用对象表示。字段对象可附属一个或多个验证函数。验证函数用来验证用户提交的输入值是否符合要求

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

NameForm 表单中有一个名为 name 的文本字段和一个名为 submit 的提交按钮。StringField类表示属性为 type="text"<input> 元素。SubmitField 类表示属性为type="submit"<input> 元素

StringField 构造函数中的可选参数 validators 指定一个由验证函数组成的列表,在接受用户提交的数据之前验证数据。验证函数 DataRequired() 确保提交的字段不为空
WTForms 支持的 HTML 标准字段如下:

  1. StringField: 用于接收文本输入的字段
  2. PasswordField: 用于接收密码输入的字段
  3. TextAreaField: 多行文本输入字段
  4. IntegerField: 用于接收整数输入的字段
  5. FloatField: 用于接收浮点数输入的字段
  6. BooleanField: 用于接收布尔值输入的字段,通常表示复选框
  7. DateField: 用于接收日期输入的字段
  8. DateTimeField: 用于接收日期时间输入的字段
  9. TimeField: 用于接收时间输入的字段
  10. FileField: 用于上传文件的字段
  11. SubmitField: 提交按钮字段,用于提交表单
  12. SelectField: 下拉菜单字段,用于提供选项供用户选择
  13. RadioField: 单选按钮字段,用于提供多个选项中的一个选项供用户选择
  14. MultipleSelectField: 多选下拉菜单字段,用于提供多个选项供用户选择

支持的验证函数如下:

  • Email: 确保字段中输入的数据是合法的电子邮件地址
  • EqualTo: 确保字段中输入的数据与另一个字段中的数据相同
  • IPAddress: 确保字段中输入的数据是合法的 IP 地址
  • Length: 确保字段中输入的数据的长度在指定的范围内
  • NumberRange: 确保字段中输入的数据在指定的数字范围内
  • Optional: 表示字段可以为空,不是必需的
  • DataRequired: 确保字段中输入的数据不为空,是必需的(老的版本为Required
  • Regexp: 根据正则表达式来验证字段中输入的数据
  • URL: 确保字段中输入的数据是合法的 URL
  • AnyOf: 确保字段中输入的数据是给定列表中的一项
  • NoneOf: 确保字段中输入的数据不是给定列表中的任何一项

把表单渲染成HTML

表单字段是可调用的,在模板中调用后会渲染成 HTML

1、视图函数把一个 NameForm 实例通过参数 form 传入模板

from flask_wtf import FlaskForm@app.route('/index')
def index():form = NameForm()return render_template('index.html', form=form)

2、在模板中可以生成一个简单的表单,如下所示

{% extends "base.html" %}{% block title %}
Index
{% endblock %}{% block head %}
{{ super() }}
{% endblock %}
{% block body %}
<form method="POST">{{ form.hidden_tag() }}{{ form.name.label }}{{ form.name() }}{{ form.submit() }}
</form>
{% endblock %}

在这个模板中,form.hidden_tag() 用于生成包含 CSRF 令牌的隐藏字段,以防止跨站请求伪造攻击。form.name.label 用于生成名为 name 字段的标签,用于显示在表单中。form.name() 用于生成名为 name 的输入字段,允许用户输入数据。form.submit() 用于生成提交按钮,用户点击此按钮可以提交表单

3、渲染的效果

image.png


在视图函数中处理表单

有时候我们不仅要渲染表单,还要接收表单中的数据

@app.route('/', methods=['GET', 'POST'])
def index():name = Noneform = NameForm()if form.validate_on_submit():name = form.name.dataform.name.data = ''  # 清空表单中的输入return render_template('index.html', form=form, name=name)

用户第一次访问程序时,服务器会收到一个没有表单数据的 GET 请求,所以 validate_on_submit() 将返回 False。if 语句的内容将被跳过,通过渲染模板处理请求,并传入表单对象和值为 None 的 name 变量作为参数。用户会看到浏览器中显示了一个表单:

在这里插入图片描述

用户提交表单后,服务器收到一个包含数据的 POST 请求。validate_on_submit() 会调用 name 字段上附属的 DataRequired() 验证函数。如果名字不为空,就能通过验证,validate_on_submit() 返回 True。现在,用户输入的名字可通过字段的 data 属性获取。在 if 语句中,把名字赋值给局部变量 name,然后再把 data 属性设为空字符串,从而清空表单字段。最后一行调用 render_template() 函数渲染模板,但这一次参数name 的值为表单中输入的名字,因此会显示一个针对该用户的欢迎消息:

在这里插入图片描述


重定向和用户会话

上述最新版的代码存在一个可用性问题。用户输入名字后提交表单,然后点击浏览器的刷新按钮,会看到一个莫名其妙的警告,要求在再次提交表单之前进行确认。之所以出现这种情况,是因为刷新页面时浏览器会重新发送之前已经发送过的最后一个请求。如果这个请求是一个包含表单数据的 POST 请求,刷新页面后会再次提交表单。大多数情况下,这并不是理想的处理方式

基于这个原因,最好别让 Web 程序把POST 请求作为浏览器发送的最后一个请求。这种需求的实现方式是,使用重定向作为 POST 请求的响应,而不是使用常规响应。重定向是一种特殊的响应,响应内容是 URL,而不是包含 HTML 代码的字符串。浏览器收到这种响应时,会向重定向的 URL 发起 GET 请求,显示页面的内容。这个页面的加载可能要多花几微秒,因为要先把第二个请求发给服务器。除此之外,用户不会察觉到有什么不同

但这种方法会带来另一个问题。程序处理 POST 请求时,使用 form.name.data 获取用户输入的名字,可是一旦这个请求结束,数据也就丢失了。因为这个 POST 请求使用重定向处理,所以程序需要保存输入的名字,这样重定向后的请求才能获得并使用这个名字,从而构建真正的响应

程序可以把数据存储在用户会话中,在请求之间“记住”数据。用户会话是一种私有存储,存在于每个连接到服务器的客户端中

@app.route('/', methods=['GET', 'POST'])
def index():form = NameForm()if form.validate_on_submit():session['name'] = form.name.datareturn redirect(url_for('index'))return render_template('index.html', form=form, name=session.get('name'))

Flash消息

请求完成后,有时需要让用户知道状态发生了变化。这里可以使用确认消息、警告或者错误提醒。一个典型例子是,用户提交了有一项错误的登录表单后,服务器发回的响应重新渲染了登录表单,并在表单上面显示一个消息,提示用户用户名或密码错误

flash() 函数可实现这种效果

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('Looks like you have changed your name!')session['name'] = form.name.datareturn redirect(url_for('index'))return render_template('index.html', form=form, name=session.get('name'))

每次提交的名字都会和存储在用户会话中的名字进行比较,而会话中存储的名字是前一次在这个表单中提交的数据。如果两个名字不一样,就会调用 flash() 函数,在发给客户端的下一个响应中显示一个消息

仅调用 flash() 函数并不能把消息显示出来,程序使用的模板要渲染这些消息。最好在基模板中渲染 Flash 消息,因为这样所有页面都能使用这些消息

{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/6153.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在智慧城市的建设中智能车载监控录像机发挥什么作用

引言 随着科技的快速发展&#xff0c;智慧城市的概念逐渐深入人心。在智慧城市的建设中&#xff0c;智能车载监控录像机作为一种重要的技术工具&#xff0c;发挥着越来越重要的作用。本文将从多个方面探讨智能车载监控录像机在智慧城市建设中的作用。 一、智能车载监控录像机概…

计算机视觉大项目(1)-水果分级系统

项目来源&#xff1a;河北大学计算机视觉课程-杨老师. 一共有四个标题&#xff0c;本篇博客只完成前两问。 目录 实验目的: 实验内容&#xff1a; 实验步骤&#xff1a; 1.水果图像的分割 >掩膜图像Mask 是什么&#xff1f; >改进:去除反光部分的影响 2&#xf…

npm install digital envelope routines::unsupported解决方法

目录 一、问题描述二、问题原因三、解决方法 一、问题描述 执行命令 npm install 报错&#xff1a;digital envelope routines::unsupported 二、问题原因 Node.js 17 版本引入了 OpenSSL 3.0&#xff0c;它在算法和密钥大小方面实施了更为严格的限制。这一变化导致 npm 的升…

excel怎么删除条件格式规则但保留格式?

这个问题的意思就是要将设置的条件格式&#xff0c;转换成单元格格式。除了使用VBA代码将格式转换外&#xff0c;还可以用excel自己的功能来完成这个任务。 一、将条件格式“留下来” 1.设置条件格式 选中数据&#xff0c;点击开始选项卡&#xff0c;设置条件格式&#xff0…

Qt绘图与图形视图之移动鼠标手动绘制任意多边形的简单介绍

往期回顾 【QT进阶】Qt线程与并发之QtConcurrent返回值与run方法的参数说明-CSDN博客 Qt绘图与图形视图之绘图技术知识点的简单介绍-CSDN博客 Qt绘图与图形视图之常见图形、路径、文字、图片的绘制介绍-CSDN博客 Qt绘图与图形视图之移动鼠标手动绘制任意多边形的简单介绍 一、…

【深度学习】第一门课 神经网络和深度学习 Week 4 深层神经网络

&#x1f680;Write In Front&#x1f680; &#x1f4dd;个人主页&#xff1a;令夏二十三 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;深度学习 &#x1f4ac;总结&#xff1a;希望你看完之后&#xff0c;能对…

临期食品店会员配送商城小程序的作用是什么

临期商品以量大价格低/即时性吸引市场大量客户&#xff0c;很多地区都有门店&#xff0c;行业也不乏连锁/加盟品牌&#xff0c;食品受众广且区域拓展性强&#xff0c;商家可线上销售提升营收和解决线下难题。 商家运用【雨科】平台搭建临期食品店商城小程序&#xff0c;对生意…

PyTorch如何修改模型(魔改)

文章目录 PyTorch如何修改模型&#xff08;魔改&#xff09;1.修改模型层(模型框架⭐)1.1通过继承修改模型1.2通过组合修改模型(重点学&#x1f440;)1.3通过猴子补丁修改模型 2.添加外部输入3.添加额外输出参考 PyTorch如何修改模型&#xff08;魔改&#xff09; 对模型缝缝补…

【算法刷题 | 动态规划02】5.02(不同路径、不同路径||、整数拆分、不同的二叉搜索树)

文章目录 5.不同路径5.1题目5.2解法一&#xff1a;深度搜索5.2.1深度搜索思路5.2.2代码实现 5.3解法二&#xff1a;动规5.3.1动规思路5.3.2代码实现 6.不同路径||6.1题目6.2解法&#xff1a;动规6.2.1动规思路&#xff08;1&#xff09;dp数组以及下标含义&#xff08;2&#x…

基于Springboot的交流互动系统

基于SpringbootVue的交流互动系统的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页 帖子信息 聚会信息 后台登录 后台管理首页 用户管理 帖子分类管理 帖子信息…

Python语言零基础入门——文件

目录 一、文件的基本概念 1.文件 2.绝对路径与相对路径 3.打开文件的模式 二、文件的读取 三、文件的追加 四、文件的写入 五、with语句 六、csv文件 1.csv文件的读取 2.csv文件的写入 七、练习题&#xff1a;实现日记本 一、文件的基本概念 1.文件 文件是以计算…

Mysql中索引的概念

索引相关概念 基础概念&#xff1a; 在MySQL中&#xff0c;索引是一种数据结构&#xff0c;用于加快数据库查询的速度和性能。索引可以帮助MySQL快速定位和访问表中的特定数据&#xff0c;就像书籍的索引一样&#xff0c;通过存储指向数据行的指针&#xff0c;可以快速…

ICode国际青少年编程竞赛- Python-1级训练场-路线规划

ICode国际青少年编程竞赛- Python-1级训练场-路线规划 1、 Dev.step(3) Dev.turnLeft() Dev.step(4)2、 Dev.step(3) Dev.turnLeft() Dev.step(3) Dev.step(-6)3、 Dev.step(-2) Dev.step(4) Dev.turnLeft() Dev.step(3)4、 Dev.step(2) Spaceship.step(2) Dev.step(3)5、…

Android手写自己的路由SDK

实现自己的路由框架 ​ 在较大型的Android app中常会用到组件化技术&#xff0c;针对不同的业务/基础功能对模块进行划分&#xff0c;从上到下为壳工程、业务模块、基础模块。其中业务模块依赖基础模块&#xff0c;壳工程依赖业务模块。同级的横向模块&#xff08;比如多个业务…

软件杯 深度学习的动物识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

MySQL-逻辑架构

1、MySQL服务器处理客户端请求 MySQL是典型的C/S架构&#xff0c;服务端程序使用 mysqld。实现效果&#xff1a;客户端进程像服务端发送&#xff08;SQL语句&#xff09;&#xff0c;服务器进程处理后再像客户端进程发送 处理结果。 2、connectors 指不同语言中与SQL的交互…

【C++】双指针算法:四数之和

1.题目 2.算法思路 这道题目十分困难&#xff0c;在leetcode上的通过率只有36%&#xff0c;大家要做好心理准备。 在做个题目前强烈建议大家先看看我的上一篇博客&#xff1a;有效三角形个数&#xff0c;看完之后再去leetcode上写一写三数之和&#xff0c;搞懂那两个题目之后…

JavaEE 初阶篇-深入了解 Junit 单元测试框架和 Java 中的反射机制(使用反射做一个简易版框架)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Junit 单元测试框架概述 1.1 使用 Junit 框架进行测试业务代码 1.2 Junit 单元测试框架的常用注解&#xff08;Junit 4.xxx 版本&#xff09; 2.0 反射概述 2.1 获…

计算机毕业设计php自行车在线租赁管理系统-vue+mysql

本系统的开发使获取自行车在线租赁管理系统信息能够更加方便快捷&#xff0c;同时也使自行车在线租赁管理系统管理信息变的更加系统化、有序化。系统界面较友好&#xff0c;易于操作。 自行车在线租赁管理系统&#xff0c;主要的模块包括首页、个人中心、用户管理、会员管理、自…

软件系统安全设计(安全保证措施)

软件安全保证措施word 软件所有全套资料获取进主页或者本文末个人名片直接。