Flask狼书笔记 | 04_表单

文章目录
- 4 表单
- 4.1 HTML表单
- 4.2 使用Flask-WTF
- 4.3 处理表单数据
- 4.4 表单进阶实践
- 小记
4 表单
表单是和用户交互最常见的方式之一,本章涉及的Python包由WTForms、Flask-WTF、Flask-CKEditor。(p104)
4.1 HTML表单
通过<form>标签创建表单,<input>标签创建字段。
<form method="post"><input type="text" name="username" placeholder="用户名">
</form>
WTForms:支持在Python中使用类定义表单,然后通过类定义生成对应的HTML代码。
4.2 使用Flask-WTF
Flask-WTF在Flask中集成了表单数据解析、CSRF保护、文件上传等功能。
# 设置密钥,flask-wtf使用程序密钥来对csrf令牌进行签名(?)
app.secret_key = 'secret string'
定义表单类:
from wtforms import Fromclass LoginForm(Form):...
- 常用的WTForms字段、实例化字段常用参数、常用的WTForms验证器,见(p107)。
输出HTML代码:
>>> form = LoginForm()
>>> form.username() # 假设在类中定义了username字段
>>> form.username.label()
- 添加额外属性:输出的字段HTML代码默认只包含
id和name属性,其他属性可以:- 1、使用render_kw属性(p109)
- 2、在调用时传入
在模板中渲染表单:我们需要把表单类实例传入模板,然后再模板中调用表单类的属性即可获取字段对应的HTML代码。
return render_template('basic.html', form=form)
<form method="post">{{ form.csrf_token }}{{ form.username.label }}{{ form.username(class='form-contorl') }} <!-- 调用时传入额外属性值 -->
</form>
-
CSRF字段:在提交表单后会自动验证该字段,为使验证通过,需渲染。
-
可以手动编写HTML表单的代码,name属性与表单类保持一致。
4.3 处理表单数据
1 过程:解析请求 --> 转换为Python数据类型 --> 验证 --> 处理。
2 提交表单:在HTML中,当<form>标签声明的表单中类型为submit的提交字段被点击时,就会创建一个提交表单的HTTP请求。
HTML表单中控制提交行为的属性:action(目标URL),method(HTTP请求方法),enctype(表单数据编码类型)。(p112)
3 验证表单数据:
- 客户端验证:可以实时动态提示用户的输入是否正确,降低服务器负载。可以通过HTML5内置的验证属性,或Javascript实现。
- 服务器端验证:必须的,因为客户端不可靠。
<!-- 使用html5属性 -->
<input type="text" name=username" required>
- WTForms验证机制:实例化表单类时传入数据,然后调用实例的
validate()方法,错误消息会存储到实例的errors属性对应的字典中。
>>> form.errors # 错误消息字典
- 获取数据:data属性是一个匹配所有字段与对应数据的字典。
>>> form.username.data
- PRG模式:(Post/Redirect/Get),在浏览器中,刷新页面时的默认行为是发送上一个请求,会导致重复提交表单。因此在处理表单后应返回一个重定向响应(GET)。
4 渲染错误消息:WTForms会把错误消息添加到表单类的errors属性中,这是一个匹配作为表单字段的类属性到对应的错误消息列表的字典。
>>> form.username.errors
4.4 表单进阶实践
简化表单处理过程的技巧,以及表单的一些非常规应用。
1 设置错误消息语言:如下,所有继承MyBaseForm的表单类,将使用新设置的错误消息默认语言。
from flask_wtf import FlaskForm app = Flask(__name__)
app.config['WTF_I18N_ENABLED'] = Falseclass MyBaseForm(FlaskForm):class Meta:locals = ['zh']class HelloFrom(MyBaseForm):...
疑惑:类内部再定义一个Meta类是什么操作?
2 使用宏渲染表单:在模板中渲染表单时,存在大量的重复工作:获取<input>定义、获取<label>定义、渲染错误消息。为了避免每一个字段重复这些代码,可以创建一个宏。(p120)
{% macro form_field(field) %}{{ field.label}}<br>{{ field(**kwargs) }}<br>{% if field.errors %}{% for error in field.errors %}{{ error }}{% endfor %}{% endif %}
{% end macro %}
3 自定义验证器:验证器是指在定义字段时传入validators参数列表的可调用对象,接受form和field(字段)两个位置参数。(p121)
- 行内验证器:在表单类中定义,用来验证某个特定的字段。
- 全局验证器:可重用。定义一个函数,在验证不通过时抛出
ValidateionError异常。若需支持参数,可用工厂函数形式。
工厂函数:返回一个可调用对象的函数。
4 文件上传:
- 渲染字段:在HTML中,渲染一个文件上传字段只需要将
<input字段的type属性值设置为file。
<input type="file">
可以使用Flask-WTF提供的FileField类创建文件上传字段,验证器包括FileRequired(是否包含文件对象)和FileAllowed(验证文件类型)。此外,可以通过限制请求报文的最大长度来限制文件大小:
app.config['MAX_CONTENT_LENGTH'] = 3 * 1024 * 1024
- 获取文件:可以在request.files中获取,解析为Werkzeug中的FileStorage对象。不过Flask-WTF会自动获取
request.files.get('photo')# 在Flask-WTF中
f = form.photo.data
- 处理文件名:可以过滤文件名中的危险字符,或统一重命名(使用uuid)。
- 其它:还有保存文件、获取保存后的文件、多文件上传等问题,此处省略,用到的时候再细看吧!
疑惑:使用uuid重命名了文件,后续如何找到这个文件呢,将文件名保存到数据库?(毕竟文件名是随机生成的)
多文件:单击一次按钮,可以一次性选择多个文件并上传。
心得笔记:感觉文件上传这一块弯弯绕绕挺多的,一时间看得有点懵。
5 使用Flask-CKEditor集成富文本编辑器:对我也是一个黑盒子 的感觉(p129)
疑惑:文本应该以什么形式保存?
6 单个表单多个提交按钮:
如“发布文章”和“保存草稿”,需根据按钮做出不同的处理。可在表单类创建多个SubmitField类型的字段,只有被点击的字段才会出现在reqeust.form字典中,而调用data属性时则会被处理为True或False。
if form.validata_on_submit():if form.save.data:...if form.publish.data:...
7 单个页面多个表单:
问题是判断当前被提交的是哪个表单。
- 单视图处理:为两个表单的提交字段设置不同的名称。
- 多视图处理:通常在一个处理表单的视图函数内包含了两类工作:渲染(GET)、处理提交的表单(POST)。因此可以单独创建一个渲染的视图函数,再为两个表单分别创建提交的视图函数。
注:表单提交请求的目标URL通过
action属性设置。
小记
表单这一节的内容比较丰富、繁杂,涉及的调包操作也较多,看完后仍有不少细节之处理解模糊。偶尔会体会到,之前看过的《Python工匠》对于我理解本书内容的帮助。
学这节的时候,我看得多,动手少,难免看了后面忘前面。一节书看完,再去看相关的源代码时却仍有些看不懂。
相关文章:
Flask狼书笔记 | 04_表单
文章目录 4 表单4.1 HTML表单4.2 使用Flask-WTF4.3 处理表单数据4.4 表单进阶实践小记 4 表单 表单是和用户交互最常见的方式之一,本章涉及的Python包由WTForms、Flask-WTF、Flask-CKEditor。(p104) 4.1 HTML表单 通过<form>标签创建…...
RabbitMQ+springboot用延迟插件实现延迟消息的发送
延迟队列:其实就是死信队列中消息过期的特殊情况 延迟队列应用场景: 可以用死信队列来实现,不过死信队列要等上一个消息消费成功,才会进行下一个消息的消费,这时候就需要用到延迟插件了,不过要线在docker上…...
多线程和并发(1)—等待/通知模型
一、进程通信和进程同步 1.进程通信的方法 同一台计算机的进程通信称为IPC(Inter-process communication),不同计 算机之间的进程通信被称为 RPC(Romote process communication),需要通过网络,并遵守共同的协议。**进…...
浏览器的事件循环
其实在我们电脑的操作系统中,每一个运行的程序都会由自己的进程(可能是一个,也可能有多个),浏览器就是一个程序,它的运行在操作系统中,拥有一组自己的进程(主进程,渲染进…...
跳跃游戏 II【贪心算法】
跳跃游戏 II class Solution {public int jump(int[] nums) {int cur 0;//当前最大覆盖路径int next 0;//下一步的最大覆盖路径int res 0;//存放结果,到达终点时最少的跳跃步数for (int i 0; i < nums.length; i) {//遍历数组,以给出数组以一个…...
promise
promise 属于事件循环的微任务,具体详见:事件循环 Promise 语法: const p1 new Promise((reslove,reject)>{console.log(2);reslove(1) }).then((data)>{console.log(3);console.log(data) }).catch((data)>{console.log(3); }) promise.th…...
前端面试:【网络协议与性能优化】HTTP/HTTPS、TCP/IP和WebSocket
嗨,亲爱的Web开发者!在构建现代Web应用时,了解网络协议是优化性能和确保安全性的关键。本文将深入探讨HTTP/HTTPS、TCP/IP和WebSocket这三个网络协议,帮助你理解它们的作用以及如何优化Web应用的性能。 1. HTTP/HTTPS协议…...
设计模式之工厂模式(万字长文)
文章目录 概述工厂模式的优点包括工厂模式有几种主要的变体看一个具体需求使用传统的方式来完成传统的方式的优缺点 简单工厂模式基本介绍使用简单工厂模式简单工厂模式的优缺点优点:缺点: 工厂方法模式看一个新的需求思路 1思路 2工厂方法模式介绍工厂方…...
CNN 02(CNN原理)
一、卷积神经网络(CNN)原理 1.1 卷积神经网络的组成 定义 卷积神经网络由一个或多个卷积层、池化层以及全连接层等组成。与其他深度学习结构相比,卷积神经网络在图像等方面能够给出更好的结果。这一模型也可以使用反向传播算法进行训练。相比较其他浅层或深度神经…...
Android View动画整理
View 动画相关内容可参考官网 动画资源 此前也有写 View 动画相关的内容,但都只是记录代码,没有特别分析。以此篇作为汇总、整理、分析。 Android View 动画有4中,分别是 平移动画 TranslateAnimation缩放动画 ScaleAnimation旋转动画 Rot…...
阿里云架构
负载均衡slb 分类以及应用场景 负载均衡slb clb 传统的负载均衡(原slb) 支持4层和7层(仅支持对uri(location),域名进行转发) 一般使用slb(clb) alb 应用负载均衡 只支持7层,整合了nginx负载均衡的各种功能,可以根据用户请求头,响应头 如果需要详细处理用户请求(浏…...
【C语言】操作符大全(保姆级介绍)
🚩纸上得来终觉浅, 绝知此事要躬行。 🌟主页:June-Frost 🚀专栏:C语言 🔥该篇将详细介绍各种操作符的功能。 目录: 📘 前言① 算术操作符②移位操作符③位操作符④赋值操…...
ruoyi-cloud部署
默认你已经安装mysql,nacos,seata,sentinel等(没有的可以先找教程安装) 1、下载源码:git clone https://gitee.com/zhangmrit/ruoyi-cloud 2、项目依赖导入,选择自己的maven环境等,创…...
Vue3(开发h5适配)
在开发移动端的时候需要适配各种机型,有大的,有小的,我们需要一套代码,在不同的分辨率适应各种机型。 因此我们需要设置meta标签 <meta name"viewport" content"widthdevice-width, initial-scale1.0">…...
图的存储:邻接矩阵法
1.邻接矩阵的实现 邻接矩阵的定义:在无向图和有向图中,使用二维数组表示各个顶点的相邻情况:1代表相邻,0表示不相邻。 代码实现: #define MaxVertexNum 100//顶点数目的最大值 typedef struct {char Vex [MaxVertexN…...
如何优雅的使用Git?
第一部分:Git的基本概念和初始设置 Git是一个分布式版本控制系统,它允许多人共同工作,同时跟踪和管理项目的版本历史。使用Git,您可以恢复旧版本、创建新分支进行实验,并与其他开发者进行协作,而不会影响主…...
【【STM32分析IO该设置什么模式的问题】】
STM32分析IO该设置什么模式的问题 我们分析而言 我们对于PA0 的设计就从此而来 对于边沿触发的选择我们已经有所了解了 我们下拉,但是当我们摁下开关的时候 从0到1 导通了 所以这个是下拉 上升沿触发 而对于KEY0 我们摁下是使得电路从原来悬空高阻态到地就是0 所以…...
飞天使-k8s基础组件分析-服务与ingress
文章目录 服务的介绍服务代理服务发现连接集群外服务服务发布无头服务 服务,pod和dns的关系端口转发通过expose 暴露应用服务案例INGRESSMetalLB使用参考文档 服务的介绍 服务的作用是啥? 提供外部调用,保证podip的真实性看看服务解决了什么…...
Unity——拖尾特效
拖尾是一种很酷的特效。拖尾的原理来自人类的视觉残留:观察快速移动的明亮物体,会看到物体移动的轨迹。摄像机通过调整快门时间,也可以拍出具有拖尾效果的照片,如在城市的夜景中,汽车的尾灯拖曳出红色的线条。 在较老…...
java开发之fastjson
依赖 <!-- fastjson依赖 --> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> <…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
