学习Flask之四、网页表单
第二章介绍的request对象,使用了客户端请求的所有信息。特别地,request.form提供了对POST请求提交的表单数据的访问。尽管Flask请求对象的支持足于处理网页单,但是还有很多作务很繁锁和重复。两个很好的例子是产生HTML表单代码和验证表单数据。
Flask-WTF扩展处理表单的体验更让人愉快。这个扩展是WTForms的 Flask集成。Flask-WTF和它的依赖可以通过pip安装:
(venv) $ pip install flask-wtf
Cross-Site Request Forgery (CSRF) 保护
黙认情况下, Flask-WTF保护所有的表单免受Cross-Site Request Forgery (CSRF)攻击。当恶意网站发送请求到攻击者登入的不同的网站时会出现CSRF攻击。
要实施 CSRF保护,Flask-WTF要求应用配置密钥。Flask-WTF用这个密钥产生加密标签来证实表单数据请求是授权的。
Example 4-1展示如何配置密钥
Example 4-1. hello.py: Flask-WTF configuration
app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'
app.config字典是框架、扩展或应用本身存贮配置信息的通用地方。配置值可以通过标准的字典符号添加到app.config。configuration对象也有函数从环境或文件中导入配置值。
SECRET_KEY配置变量被Flask和其它扩展用作通用密钥。如它的名字所示,加密的强度取决于变量的值。在不同的应用中使用不同的密钥并确保这个字符串不被别人知道。为了增强安全性,密钥应贮存于环境变量中而不是被嵌入到代码中。这个技术描述于第7章。
Form类
Flask-WTF时,每一个网页表单由一个类来呈现它继承自Form类。这个类定义了表单中字段的列表,每个字段呈现为一个对象。每个字段对象可以附着一个或多个验证器。验证器是检查用户输入的函数。
Example 4-2 展示一个简单的表单,它有一个文本字段和一个提交字段。
Example 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以及一个提交按钮。StringField类呈现为<input>元素具有type="text"的属性。SubmitField类呈现<input>元素具有 type="submit"属性。field构造函数的第一个参数是宣染表单时的label。
StringField 构造器中包含的可选的验证器参数定义了检查器的列表,它们在接受前作用于用户提交的数据。Required()验证器确保提效的字段非空。表单的基类被Flask-WTF 扩展定义,所以它导入自flask_wtf。但是字段和验证器自接从WTForms包导入。
WTForms支持的标准的HTML字段列表见Table 4-1.见:
http://www.aluoyun.cn/details.php?article_id=194
WTForms内在验证器的列表展示于Table 4-2. 见:
http://www.aluoyun.cn/details.php?article_id=195
表单的HTML宣染
表单字段是可调用的,即从模板宣染它们到HTML。假如view函数传递一个NameForm实例到模板作为参数,模板会产生简单的HTML表单:
<form method="POST">
{{ form.name.label }} {{ form.name() }}
{{ form.submit() }}
</form>
当然结果是很粗的。要改进表单的外观,宣染字段的传入参数被转换为字段的HTML属性。
作为例子,你可以给出字段id或class属性然后定义CSS格式:
<form method="POST">
{{ form.name.label }} {{ form.name(id='my-text-field') }}
{{ form.submit() }}
</form>
但是即使具有HTML属性,用这种方法宣染表单的工作也很多,所以最好是尽可能使用Bootstrap的表单风格。
Flask-Bootstrap提供了非常高级的帮助函数来宣染Flask WTF表单,它使用Bootstrap预定义的表单式样,每个式样都有一个调用。使用Flask Bootstrap,前面的表单可以如下宣染:
{% import "bootstrap/wtf.html" as wtf %}
{{ wtf.quick_form(form) }}
import指令与正常的Python脚本的的作用一样并允许模板元素被导入并在许多模板中使用。 导入的bootstrap/wtf.html 文件定义帮助函数来宣染Flask-WTF表单使用Bootstrap。
wtf.quick_form()函数取Flask-WTF表单对象并宣染它用黙认的Bootstrap式样。hello.py完整的模板见Example 4-3。
Example 4-3. templates/index.html: Using Flask-WTF and Flask-Bootstrap to render a form
{% 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 %}
现在模板的content区域有两个节。第一个节是网页的header展示欢迎。这里使用了模板条件。Jinja2的条件的格式为{% if variable %}...{% else %}...{% endif %}。如果条件为真,则if 与else之间的内容被宣染到模板。如果条件为假,则else和endif之间的内容被宣染。
示例的模板宣染 “Hello, Stranger!” 当name模板参数不提供时。内容的第二节宣染NameForm对象使用wtf.quick_form()函数。
View函数中处理表单
在新版的hello.py文件里,view函数index()将宣染表单并接收数据。Example 4-4展示更新的view函数index()。
Example 4-4. hello.py: Route methods
@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)
app.route装饰器中添加的方法参数告诉Flask注册view函数作为URL map中 GET 和 POST 请求的处理器。当不指定方法时,view函数只处理GET请求。
在方法列表中增加POST是必要的因为提交的表单用 POST请求更方便。也有可能用GET请求提交表单,但是GET请求没有主体,数据以查询字符串的方式附加在URL里并在浏览器的地址栏内是可见的。出于这个和其它原因,表单提交几乎都用POST请求。用局部name变量贮存接收自表单的name。当 name未知时,变量初始化为None。 view函数创建NameForm类的实例来呈现表单。
validate_on_submit()方法返回真当表单提交时,并且数据被字段验证器接收。在其它情况下,validate_on_submit()返回假。
方法的返回值确定表单是否被宣染或被处理。当用户第一次导航到应用时,服务器接收不带表单数据的GET请求,所以validate_on_submit() 返回False。if语句的主体将跳过,请求被处理通过宣染模板,它获得表单对象并将name变量设为None作为参数。用户现在可以看到浏览器中的表单。当用户提交表单时,服务器接收 POST请求的数据。validate_on_submit()调用附着于name字段的Required()验证器。如果name不是空的,则验证器接受它validate_on_submit()返回真。现在用户输入的name可以作为字段的data属性访问。在if语句的主体内,name被赋给局部变量并且 form字段被清除,通过设置数据属性为空字符串。最后一行调用的render_template()宣染模板,但是这次name参数包含来自表单的name,所以欢迎被个性化。
当用户提交name时,应用用个性化欢迎进行响应。表单还在下面,所以用户还可以提交新的name ,如果想要的话。
如果用户用空的name提交表单,Required()验证器抛出错误。注意功能是自动的。这是设计良好的Flask-WTF和Flask-Bootstrap扩展给你的应用强大的例子。
重定向和用户会话
上一版本的hello.py有个使用问题。如果你输入你的name并提交它,然后点击浏览器的刷新按钮,你会得到警告要求确认再重新提交表单。这是因为浏览器重复上一次的请求当它们请求刷新网页时。当最后一次发送POST请求使用表单数据时,刷新会导致单表的重复提交,这不是期望的行为。许多用户不理解浏览器的警告。因此,它被认为是网页应用的良好实践,不漏掉浏览器发送的最后一次POST请求。这个实践可以通过重定向响应POST请求而不是正常的请求来获得。重定向是一种特殊的响应,它有URL而不是HTML代码的字串。当浏览器接受这个响应时,它发送GET请求重定向的URL,那就是显示的页面。页面会取更长的时间来加载因为第二个请求要发送到服务器,除此之外用户不会看到别的不同。现在最后一个请求是GET,所以刷新命令如期执行。这种技巧称为Post/ Redirect/Get模式。但是这种方法有另一个问题。当应用处理POST请求时,它访问存贮于form.name.data的用户输入的name,但是请求结束时表单数据消失。因为表单数据用重定向处理,应用需要存贮 name以使重定向请求可以得到它并用它构建实际的响应。应用可以记住一个请求的东西到下一次请求通过将它们存贮在用户会话里,用户会话是私有的存贮或以被每个连接的客户端使用。
用户会话在第二章作为与请求上下文相关的变量介绍。
它调用会话并像标准的python字典一样访问。
Example 4-5 展示新版的index() view函数,它实施重定向和用户会话。
Example 4-5. hello.py: Redirects and user sessions
from flask import Flask, render_template, session, redirect, url_for
@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'))
在上一个版本的应用中,局部变量name用于贮存用户在表单中输入的name。那个变量现在放在用户会话中,作为session['name'],以便它在请求外被记住。现在有有效表单数据的请求以调用redirect()结束, redirect()是一个产生HTTP重定向请求的帮助函数。redirect()取URL作为重定向参数。本例中的重定向URL是根URL,所以响应与redirect('/')更一致,但是实际上使用lask的URL生成函数url_for()。鼓劢使用url_for()产生URLs因为这个函数使用URL map产生URLs,所以URLs确保兼容定义的路由和任何路由名的变更可以自动获得当用这个函数时。 url_for()函数第一个和唯一要求的参数是endpoint名,每个路由拥有的内部名。黙认情况,路由的endpoint是 view函数名。本例中,处理根URL的view函数是index(),所以提供给url_for()的name参数是 index。最后的改变在 render_template()函数里,它现在从会话中直接获得name参数,使用session.get('name')。与使用正常的字典一样,使用get() 请求字典的key避免意外,对于未找到的keys,因为get()返回黙认的值None对于缺失的key。对于这个版本的应用,你可以看到刷新会得到你想要的结果。
消息推出
有时在请求完成后给用户一个状态更新是有用的。这可以是一个确认信息,警告,或错误。一个典型的例子是当你提交错误的登录表单时,服务器重新宣染登录表单并在其上面出现消息告诉你用户名或密码无效。
Flask包含了这种功能作为核心特征。Example 4-6 展示如何使用flash()函数来实现这个目的。
Example 4-6. hello.py: Flashed messages
from flask import Flask, render_template, session, redirect, url_for, flash
@app.route('/', methods=['GET', 'POST'])
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.data
form.name.data = ''
return redirect(url_for('index'))
return render_template('index.html',
form = form, name = session.get('name'))
本例中,每次提交name,都与存贮在用户会话中的name比较。如果两个names不同, flash()函数被调用并显示于下一个返回客户端的响应中。
调用flash()并不足于使消息显示;应用使用的模板需要宣染这些消息。宣染推出的消息的最好的地方是基模板,因这它会在所有网页中使能这些消息。Flask有一个get_flashed_messages() 函数供模板使用以追踪消息和宣染他们,如Example 4-7所示。
Example 4-7. templates/base.html: Flash message rendering
{% block content %}
<div class="container">
{% for message in get_flashed_messages() %}
<div class="alert alert-warning">
<button type="button" class="close" data-dismiss="alert">×</button>
{{ message }}
</div>
{% endfor %}
{% block page_content %}{% endblock %}
</div>
{% endblock %}
本例中,消息被宣染,使用Bootstrap的CSS。
使用一个循环,因为有多个消息要显示,每次调用 flash() 都要显示。从get_flashed_messages()得到的消息不会在这个函数下一次调用时返回。所以推出的消息只显示一次然后消失。 能从网页表单接受用户数据是许多应用要求的特征,永久存贮数据也是许多应用要求的特征。下一章的主题是使用Flask的数据支持。
相关文章:
学习Flask之四、网页表单
第二章介绍的request对象,使用了客户端请求的所有信息。特别地,request.form提供了对POST请求提交的表单数据的访问。尽管Flask请求对象的支持足于处理网页单,但是还有很多作务很繁锁和重复。两个很好的例子是产生HTML表单代码和验证表单数据…...
CenterMask paper笔记
CenterMask是一个anchor free的实例分割模型, 来自paper: CenterMask: Real-Time Anchor-Free Instance Segmentation 提起anchor free, 会想到FCOS模型,是用来目标检测的, 那么这里就用到了FCOS, 不过换了backbone, 在FCOS检测出目标框后&…...
06- OpenCV查找图像轮廓 (OpenCV基础) (机器视觉)
知识重点 灰度图转换: gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)二值化: 返回两个东西,一个阈值, 一个是二值化的图: thresh, binary cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)查找轮廓: 返回两个结果,分别是轮廓和层级: c…...
OpenGL学习日记之模型绘制
自己编译运行过程中遇到的一些问题 下载Assimp已编译的lib(因为我们公司的电脑有很多权限和限制,也不能自己安装一些没有报备的软件,所以愁方便我就没有用cMake自己编译了)找到一位免费分享的博主的。 https://blog.csdn.net/lady_killer9/article/deta…...
Springboot接口多个DTO入参的Postman上传方式
在Java中使用Spring Boot框架时,可以同时使用多个DTO作为方法参数。 TO(Data Transfer Object)是一个常见的设计模式,用于封装数据传输对象。它通常用于将数据从一个层传递到另一个层,例如将数据从服务层传递到控制器…...
软考各科目考核内容详细介绍,看这里
新手在准备报考软考时,都会遇到这样的一个问题——科目这么多,我适合考什么?要想知道自己适合报什么科目,就需要了解每个科目是什么,考什么等一系列的问题。 接下来,就为大家介绍一下软考的各个科目&#…...
连续时间信号与离散时间信号
前言 《信号与系统》是一门很难的课,也是许多学校考研要考的专业课,由于每周只有两节课,所以每次上完都要及时的去复习,这里参考的教材是奥本海姆著作,刘海棠译,北京:电子工业出版社࿰…...
TPM密钥管理、使用
前面讲过证书相关内容,除了在软件方面有所应用外,在硬件方面也有很多应用。本次讲一下TPM相关的内容。 一、TPM介绍 1.1背景 TCG基于硬件安全的架构是为应对1990s后期日益增多的复杂恶意软件攻击应用而生的。当时以及现在,抵御PC客户端网络…...
return和finally执行顺序、运行时异常与一般异常异同、error和exception区别、Java异常处理机制原理与应用
文章目录1.try {}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?2.运行时异常与一般异常有何异同?3.java 程序中的错误有三种类型分别是什么4.error和exception有什么…...
我为什么放弃WinUI3
基于WinUI3开发HiNote已经有一个多月的时间了,算是做出来一个简单能用的C端软件。 基于个人的经历,说说其中的开发体验。 UI设计语言 无论是否抄袭苹果,WinUI3给人的感觉都是眼前一亮的。简洁美观,现代化,毛玻璃的美…...
2023年全国最新安全员精选真题及答案2
百分百题库提供安全员考试试题、建筑安全员考试预测题、建筑安全员ABC考试真题、安全员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 21.(单选题)静作用压路机在施工过程,要求实际含水量…...
计算机408考研先导课---C语言难点
以下为小编在重温C语言时,容易犯错的一些点,希望列出来对大家有一定帮助! 一、整型变量数的范围 类型说明符长度(字节)数的范围int4/2(有些为4字节,有些为2字节)-32768~32767short2…...
K8S 部署 Redis-Cluster 集群
本文使用 bitnami 镜像部署 redis-cluster 官方文档:https://github.com/bitnami/charts/tree/main/bitnami/redis-cluster 添加 bitnami 仓库 helm repo add bitnami https://charts.bitnami.com/bitnami自定义 values.yaml storageClass:集群的存储…...
[oeasy]python0089_大型机的衰落_Dec小型机崛起_PDP_VAX网络
编码进化 回忆上次内容 上次 回顾了 计算机存储单位的演变 最小的读写单位 是 bit 8-bit 固定下来 成为了字节(Byte) 位数容量8-bit1Byte1024Byte1 KB1024 KB1 MB1024 MB1 GB1024 GB1 TB 存储字符时 第1位 是 标志位后7位 是 ascii具体的值 可以用 1Byte 存储 计算机之间 …...
Apache Shiro与Spring Security对比
Apache Shiro VS Spring Security 1.Spring Security 官方文档:https://spring.io/projects/spring-security#overview介绍: Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spr…...
23春招-mysql事务相关高频面试题
1、什么是事务 对于一个事务,要么事务内的sql全部执行,要么都不执行 2、 事务的特性ACID 原子性 整个事务中所有的操作要么全部提交成功,要么全部失败会滚。 一致性 数据库总是从一个一致性状态转换到另一个一致性状态。假如有三个sql语句…...
天线理论知识1——基础概念介绍
基础概念介绍 文章目录 基础概念介绍前言一、主要参数二、天线的种类三、天线的测量前言 天线是用于发射和接收电磁波设备。其功能可以概括为转换自由空间中的电磁波和设备中的导行波。 一、主要参数 天线设计中要考虑的参数较多,包括 方向性函数:距离天线 r r r处的远区…...
【云原生之Docker实战】使用Docker部署StackEdit在线Markdown编辑器
【云原生之Docker实战】使用Docker部署StackEdit在线Markdown编辑器 一、StackEdit介绍1.StackEdit简介2.StackEdit中文版简介3.StackEdit中文版功能二、检查本地Docker环境1.检查系统版本2.检查系统Docker版本3.检查docker compose版本三、下载StackEdit镜像四、部署StackEdit…...
特征工程:特征构造以及时间序列特征构造
数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。由此可见,特征工程在机器学习中占有相当重要的地位。在实际应用当中,可以说特征工程是机器学习成功的关键。 那特征工程是什么? 特征工程是利用数据领域的相关…...
单master部署简要步骤
准备多台服务器,选定一台为master例如设置ip为192.168.0.10,host: k8s.master,其他分别为 k8s.s11 192.168.0.11k8s.s12 192.168.0.12....hostname可以使用命令配置hostname k8s.masterip解析可以在hosts文件中写入,如果有内部dns解析可以在内…...
Windows ISO制作与补丁集成自动化工具实战指南:从手动操作到批量部署的效率革命
Windows ISO制作与补丁集成自动化工具实战指南:从手动操作到批量部署的效率革命 【免费下载链接】Win_ISO_Patching_Scripts Win_ISO_Patching_Scripts 项目地址: https://gitcode.com/gh_mirrors/wi/Win_ISO_Patching_Scripts 在数字化时代,系统…...
ESP32-S3实战指南:SPI多设备管理与高效数据传输
1. ESP32-S3的SPI总线基础认知 第一次接触ESP32-S3的SPI总线时,我完全被各种专业术语搞懵了。后来在实际项目中反复折腾才发现,SPI本质上就是个"快递小哥",负责在芯片和外围设备之间搬运数据。ESP32-S3内置了4个这样的"快递站…...
K8s中pod的创建与销毁
刚开始学习,整了一下流程图1.pod的创建2.pod的销毁有不对的地方,大家共同探讨...
国产N32芯片开发避坑指南:J-Link在Keil中的特殊配置(含Cortex-M0配置模板)
国产N32芯片开发实战:J-Link调试配置深度解析与Keil环境优化 在国产MCU生态快速崛起的背景下,N32系列芯片凭借优异的性价比和本土化服务优势,正逐步成为工程师替代进口方案的新选择。然而,从传统ST芯片转向国产平台时,…...
Qwen3-VL-30B部署避坑指南:从下载到运行一气呵成
Qwen3-VL-30B部署避坑指南:从下载到运行一气呵成 1. 为什么选择Qwen3-VL-30B Qwen3-VL-30B是目前通义千问系列中最强大的视觉-语言模型,它在多个方面实现了显著提升: 更优秀的文本理解和生成:能够处理复杂语义和长文本更深入的…...
汽车电子选型:RF430F5144CIRKVRQ1为什么适合发动机舱附近的应用
RF430F5144CIRKVRQ1:这颗77mm的QFN芯片,如何把13.56MHz NFC和MSP430 MCU塞进一颗汽车级SoCRF430F5144CIRKVRQ1来自德州仪器,是一颗高度集成的NFC传感器收发器SoC。它的核心价值很直接:把13.56MHz HF射频前端、16位MSP430超低功耗M…...
Ollama实测:Yi-Coder-1.5B代码生成速度有多快?3秒搞定日常函数
Ollama实测:Yi-Coder-1.5B代码生成速度有多快?3秒搞定日常函数 1. 测试背景与目标 作为一名开发者,每天都要面对各种编码任务。从简单的工具函数到复杂的算法实现,代码生成速度直接影响着开发效率。Yi-Coder-1.5B作为一款开源的…...
Inconsolata字体高效使用实战指南:提升编程体验的专业字体方案
Inconsolata字体高效使用实战指南:提升编程体验的专业字体方案 【免费下载链接】Inconsolata Development repo of Inconsolata Fonts by Raph Levien 项目地址: https://gitcode.com/gh_mirrors/in/Inconsolata 作为开发者,我们每天与代码打交道…...
深圳小学数学期末试卷创新题型引热议,数学与文学跨界融合成焦点
1. 当数学题遇上古诗词:深圳试卷创新设计背后的教育逻辑 深圳某区五年级数学期末卷上的一道"跨界题"最近在家长群炸开了锅。题目要求学生分析函数单调性后,将其与《琵琶行》中琵琶女的情感变化对应起来。这种"数学古诗文"的混搭模式…...
Mermaid Live Editor:5分钟快速创建专业图表的终极免费工具
Mermaid Live Editor:5分钟快速创建专业图表的终极免费工具 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid-live-e…...
