【Flask使用】全知识md文档,4大部分60页第3篇:Flask模板使用和案例

本文的主要内容:flask视图&路由、虚拟环境安装、路由各种定义、状态保持、cookie、session、模板基本使用、过滤器&自定义过滤器、模板代码复用:宏、继承/包含、模板中特有变量和函数、Flask-WTF 表单、CSRF、数据库操作、ORM、Flask-SQLAlchemy、增删改查操作、案例、蓝图、单元测试
全套Flask笔记直接地址: 请移步这里
共 4 章,42 子模块


模板
- 基本使用
- 过滤器&自定义过滤器
- 控制代码块
- 宏、继承、包含
- Flask 的模板中特有变量和方法
- web表单
- CSRF
学习目标
- 能够写出 jinja2 中变量代码块和控制代码块的格式
- 能够写出在模板中字典,列表的取值方式
- 能够写出数组反转的自定义过滤器(使用1种方式即可)
- 能够说出Flask中模板代码复用的三种方式
- 能够使用代码实现模板继承的功能
- 能够说出可以在模板中直接使用的 Flask 变量和函数
- 能够使用 Flask-WTF 扩展实现注册表单
- 能够说出 CSRF 攻击的原理
模板的使用
- 在项目下创建
templates文件夹,用于存放所有的模板文件,并在目录下创建一个模板html文件temp_demo1.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
我的模板html内容
</body>
</html>
- 设置 templates 文件夹属性以便能够在代码中有智能提示

- 设置 html 中的模板语言,以便在 html 有智能提示

- 创建视图函数,将该模板内容进行渲染返回
@app.route('/')
def index():return render_template('temp_demo1.html')
访问:http://127.0.0.1:5000/ 运行测试
- 代码中传入字符串,列表,字典到模板中
@app.route('/')
def index():# 往模板中传入的数据my_str = 'Hello 黑马程序员'my_int = 10my_array = [3, 4, 2, 1, 7, 9]my_dict = {'name': 'xiaoming','age': 18}return render_template('temp_demo1.html',my_str=my_str,my_int=my_int,my_array=my_array,my_dict=my_dict)
- 模板中代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
我的模板html内容
<br/>{{ my_str }}
<br/>{{ my_int }}
<br/>{{ my_array }}
<br/>{{ my_dict }}</body>
</html>
- 运行效果
Hello 黑马程序员
10
[3, 4, 2, 1, 7, 9]
{‘name’: ‘xiaoming’, ‘age’: 18}Code injected by live-server
- 相关运算,取值
<br/> my_int + 10 的和为:{{ my_int + 10 }}
<br/> my_int + my_array第0个值的和为:{{ my_int + my_array[0] }}
<br/> my_array 第0个值为:{{ my_array[0] }}
<br/> my_array 第1个值为:{{ my_array.1 }}
<br/> my_dict 中 name 的值为:{{ my_dict['name'] }}
<br/> my_dict 中 age 的值为:{{ my_dict.age }}
- 结果
my_int + 10 的和为:20
my_int + my_array第0个值的和为:13
my_array 第0个值为:3
my_array 第1个值为:4
my_dict 中 name 的值为:xiaoming
my_dict 中 age 的值为:18
过滤器
过滤器的本质就是函数。有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化、运算等等,而在模板中是不能直接调用 Python 中的某些方法,那么这就用到了过滤器。
使用方式:
- 过滤器的使用方式为:变量名 | 过滤器。
{{variable | filter_name(*args)}}
- 如果没有任何参数传给过滤器,则可以把括号省略掉
{{variable | filter_name}}
- 如:``,这个过滤器的作用:把变量variable 的值的首字母转换为大写,其他字母转换为小写
链式调用
在 jinja2 中,过滤器是可以支持链式调用的,示例如下:
{{ "hello world" | reverse | upper }}
常见内建过滤器
字符串操作
- safe:禁用转义
<p>{{ '<em>hello</em>' | safe }}</p>
- capitalize:把变量值的首字母转成大写,其余字母转小写
<p>{{ 'hello' | capitalize }}</p>
- lower:把值转成小写
<p>{{ 'HELLO' | lower }}</p>
- upper:把值转成大写
<p>{{ 'hello' | upper }}</p>
- title:把值中的每个单词的首字母都转成大写
<p>{{ 'hello' | title }}</p>
- reverse:字符串反转
<p>{{ 'olleh' | reverse }}</p>
- format:格式化输出
<p>{{ '%s is %d' | format('name',17) }}</p>
- striptags:渲染之前把值中所有的HTML标签都删掉
<p>{{ '<em>hello</em>' | striptags }}</p>
列表操作
- first:取第一个元素
<p>{{ [1,2,3,4,5,6] | first }}</p>
- last:取最后一个元素
<p>{{ [1,2,3,4,5,6] | last }}</p>
- length:列表长度
<p>{{ [1,2,3,4,5,6] | length }}</p>
- sum:列表求和
<p>{{ [1,2,3,4,5,6] | sum }}</p>
- sort:列表排序
<p>{{ [6,2,3,1,5,4] | sort }}</p>
语句块过滤
{% filter upper %}#一大堆文字#
{% endfilter %}
自定义过滤器
过滤器的本质是函数。当模板内置的过滤器不能满足需求,可以自定义过滤器。自定义过滤器有两种实现方式:
- 一种是通过Flask应用对象的 add_template_filter 方法
- 通过装饰器来实现自定义过滤器
重要:自定义的过滤器名称如果和内置的过滤器重名,会覆盖内置的过滤器。
需求:添加列表反转的过滤器
方式一
通过调用应用程序实例的 add_template_filter 方法实现自定义过滤器。该方法第一个参数是函数名,第二个参数是自定义的过滤器名称:
def do_listreverse(li):# 通过原列表创建一个新列表temp_li = list(li)# 将新列表进行返转temp_li.reverse()return temp_liapp.add_template_filter(do_listreverse,'lireverse')
方式二
用装饰器来实现自定义过滤器。装饰器传入的参数是自定义的过滤器名称。
@app.template_filter('lireverse')
def do_listreverse(li):# 通过原列表创建一个新列表temp_li = list(li)# 将新列表进行返转temp_li.reverse()return temp_li
- 在 html 中使用该自定义过滤器
<br/> my_array 原内容:{{ my_array }}
<br/> my_array 反转:{{ my_array | lireverse }}
- 运行结果
my_array 原内容:[3, 4, 2, 1, 7, 9]
my_array 反转:[9, 7, 1, 2, 4, 3]
控制代码块
控制代码块主要包含两个:
- if/else if /else / endif
- for / endfor
if语句
Jinja2 语法中的if语句跟 Python 中的 if 语句相似,后面的布尔值或返回布尔值的表达式将决定代码中的哪个流程会被执行:
{%if user.is_logged_in() %}<a href='/logout'>Logout</a>
{% else %}<a href='/login'>Login</a>
{% endif %}
过滤器可以被用在 if 语句中:
{% if comments | length > 0 %}There are {{ comments | length }} comments
{% else %}There are no comments
{% endif %}
循环
- 我们可以在 Jinja2 中使用循环来迭代任何列表或者生成器函数
{% for post in posts %}<div><h1>{{ post.title }}</h1><p>{{ post.text | safe }}</p></div>
{% endfor %}
- 循环和if语句可以组合使用,以模拟 Python 循环中的 continue 功能,下面这个循环将只会渲染post.text不为None的那些post:
{% for post in posts if post.text %}<div><h1>{{ post.title }}</h1><p>{{ post.text | safe }}</p></div>
{% endfor %}
- 在一个 for 循环块中你可以访问这些特殊的变量:
| 变量 | 描述 |
|---|---|
| loop.index | 当前循环迭代的次数(从 1 开始) |
| loop.index0 | 当前循环迭代的次数(从 0 开始) |
| loop.revindex | 到循环结束需要迭代的次数(从 1 开始) |
| loop.revindex0 | 到循环结束需要迭代的次数(从 0 开始) |
| loop.first | 如果是第一次迭代,为 True 。 |
| loop.last | 如果是最后一次迭代,为 True 。 |
| loop.length | 序列中的项目数。 |
| loop.cycle | 在一串序列间期取值的辅助函数。见下面示例程序。 |
-
在循环内部,你可以使用一个叫做loop的特殊变量来获得关于for循环的一些信息
- 比如:要是我们想知道当前被迭代的元素序号,并模拟Python中的enumerate函数做的事情,则可以使用loop变量的index属性,例如:
{% for post in posts%}
{{loop.index}}, {{post.title}}
{% endfor %}
- 会输出这样的结果
1, Post title
2, Second Post
- cycle函数会在每次循环的时候,返回其参数中的下一个元素,可以拿上面的例子来说明:
{% for post in posts%}
{{loop.cycle('odd','even')}} {{post.title}}
{% endfor %}
- 会输出这样的结果:
odd Post Title
even Second Post
示例程序
- 实现的效果

- 准备数据
# 只显示4行数据,背景颜色依次为:黄,绿,红,紫my_list = [{"id": 1,"value": "我爱工作"},{"id": 2,"value": "工作使人快乐"},{"id": 3,"value": "沉迷于工作无法自拔"},{"id": 4,"value": "日渐消瘦"},{"id": 5,"value": "以梦为马,越骑越傻"}
]
- 模板代码
{% for item in my_list if item.id != 5 %}{% if loop.index == 1 %}<li style="background-color: orange">{{ item.value }}</li>{% elif loop.index == 2 %}<li style="background-color: green">{{ item.value }}</li>{% elif loop.index == 3 %}<li style="background-color: red">{{ item.value }}</li>{% else %}<li style="background-color: purple">{{ item.value }}</li>{% endif %}
{% endfor %}
模板代码复用
在模板中,可能会遇到以下情况:
- 多个模板具有完全相同的顶部和底部内容
- 多个模板中具有相同的模板代码内容,但是内容中部分值不一样
- 多个模板中具有完全相同的 html 代码块内容
像遇到这种情况,可以使用 JinJa2 模板中的 宏、继承、包含来进行实现
宏
对宏(macro)的理解:
- 把它看作 Jinja2 中的一个函数,它会返回一个模板或者 HTML 字符串
- 为了避免反复地编写同样的模板代码,出现代码冗余,可以把他们写成函数以进行重用
- 需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有模板中,以避免重复
使用
- 定义宏
{% macro input(name,value='',type='text') %}<input type="{{type}}" name="{{name}}"value="{{value}}" class="form-control">
{% endmacro %}
- 调用宏
{{ input('name' value='zs')}}
- 这会输出
<input type="text" name="name"value="zs" class="form-control">
- 把宏单独抽取出来,封装成html文件,其它模板中导入使用,文件名可以自定义macro.html
{% macro function(type='text', name='', value='') %}
<input type="{{type}}" name="{{name}}"
value="{{value}}" class="form-control">{% endmacro %}
- 在其它模板文件中先导入,再调用
{% import 'macro.html' as func %}
{% func.function() %}
代码演练
- 使用宏之前代码
<form><label>用户名:</label><input type="text" name="username"><br/><label>身份证号:</label><input type="text" name="idcard"><br/><label>密码:</label><input type="password" name="password"><br/><label>确认密码:</label><input type="password" name="password2"><br/><input type="submit" value="注册">
</form>
- 定义宏
{#定义宏,相当于定义一个函数,在使用的时候直接调用该宏,传入不同的参数就可以了#}
{% macro input(label="", type="text", name="", value="") %}
<label>{{ label }}</label><input type="{{ type }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}
- 使用宏
<form>{{ input("用户名:", name="username") }}<br/>{{ input("身份证号:", name="idcard") }}<br/>{{ input("密码:", type="password", name="password") }}<br/>{{ input("确认密码:", type="password", name="password2") }}<br/>{{ input(type="submit", value="注册") }}
</form>
模板继承
模板继承是为了重用模板中的公共内容。一般Web开发中,继承主要使用在网站的顶部菜单、底部。这些内容可以定义在父模板中,子模板直接继承,而不需要重复书写。
- 标签定义的内容
{% block top %} {% endblock %}
- 相当于在父模板中挖个坑,当子模板继承父模板时,可以进行填充。
- 子模板使用 extends 指令声明这个模板继承自哪个模板
- 父模板中定义的块在子模板中被重新定义,在子模板中调用父模板的内容可以使用super()
父模板
- base.html
{% block top %}顶部菜单
{% endblock top %}{% block content %}
{% endblock content %}{% block bottom %}底部
{% endblock bottom %}
子模板
- extends指令声明这个模板继承自哪
{% extends 'base.html' %}
{% block content %}需要填充的内容
{% endblock content %}
-
模板继承使用时注意点:
- 不支持多继承
- 为了便于阅读,在子模板中使用extends时,尽量写在模板的第一行。
- 不能在一个模板文件中定义多个相同名字的block标签。
- 当在页面中使用多个block标签时,建议给结束标签起个名字,当多个block嵌套时,阅读性更好。
未完待续 下一期下一章
全套笔记直接地址: 请移步这里
相关文章:
【Flask使用】全知识md文档,4大部分60页第3篇:Flask模板使用和案例
本文的主要内容:flask视图&路由、虚拟环境安装、路由各种定义、状态保持、cookie、session、模板基本使用、过滤器&自定义过滤器、模板代码复用:宏、继承/包含、模板中特有变量和函数、Flask-WTF 表单、CSRF、数据库操作、ORM、Flask-SQLAlchemy…...
芯片的测试方法
半导体的生产流程包括晶圆制造和封装测试,在这两个环节中分别需要完成晶圆检测(CP, Circuit Probing)和成品测试(FT, Final Test)。无论哪个环节,要测试芯片的各项功能指标均须完成两个步骤:一是将芯片的引脚与测试机的功能模块连接起来&…...
网络安全等级保护2.0国家标准
等级保护2.0标准体系主要标准如下:1.网络安全等级保护条例2.计算机信息系统安全保护等级划分准则3.网络安全等级保护实施指南4.网络安全等级保护定级指南5.网络安全等级保护基本要求6.网络安全等级保护设计技术要求7.网络安全等级保护测评要求8.网络安全等级保护测评…...
从根到叶:随机森林模型的深入探索
一、说明 在本综合指南中,我们将超越基础知识。当您盯着随机森林模型的文档时,您将不再对“节点杂质”、“加权分数”或“成本复杂性修剪”等术语感到不知所措。相反,我们将剖析每个参数,阐明其作用和影响。通过理论和 Python 实践…...
python数据结构与算法-15_堆与堆排序
堆(heap) 前面我们讲了两种使用分治和递归解决排序问题的归并排序和快速排序,中间又穿插了一把树和二叉树, 本章我们开始介绍另一种有用的数据结构堆(heap), 以及借助堆来实现的堆排序,相比前两种排序算法要稍难实现一些。 最后我…...
vscode提交代码到Gitee(保姆教程)
Visual Studio Code(VSCode) 提交代码到Gitee(保姆教程) 1 环境配置1.1 git本地安装1.2 Vscode安装1.3 配置注册gitee账号 2 Vscode代码提交到Gitee2.1 新建仓库2.2 Vscode提交代码 1 环境配置 电脑需要已经安装好的Vscode已经配…...
【洛谷算法题】P5714-肥胖问题【入门2分支结构】
👨💻博客主页:花无缺 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5714-肥胖问题【入门2分支结构】🌏题目描述🌏输入格式&a…...
促进材料基因工程基础理论、前沿技术和关键装备的发展和应用,第七届材料基因工程高层论坛将于12月重庆举办,龙讯旷腾出席会议
为了进一步促进材料基因工程基础理论、前沿技术和关键装备的发展和应用,加强国际交流,加速我国新材料的研发和应用,由中国材料研究学会、西部科学城重庆高新区管理委员会主办,重庆大学、北京科技大学、北京云智材料大数据研究院等…...
Cypress-浏览器操作篇
Cypress-浏览器操作篇 页面的前进与后退 后退 cy.go(back); cy.go(-1);前进 cy.go(forward); cy.go(1);页面刷新 cy.reload() cy.reload(forceReload) cy.reload(options) cy.reload(forceReload, options)**options:**只有 timeout 和 log forceReload 是否…...
短视频矩阵系统源码搭建部署分享
一、 短视频矩阵系统源码搭建部署分享 目录 一、 短视频矩阵系统源码搭建部署分享 二、短视频矩阵系统搭建功能设计 三、 抖音矩阵号矩阵系统功能设计原则 四、 短视频矩阵开发部分源码展示 很高兴能够帮助您,以下是短视频矩阵系统源码搭建部署分享:…...
科技赋能,创新发展!英码科技受邀参加2023中国创新创业成果交易会
11月17日至19日,2023中国创新创业成果交易会(简称:创交会)在广州市广交会展馆圆满举行。英码科技受邀参加本届创交会,并在会场展示了创新性的AIoT产品、深元AI引擎和行业热门解决方案。 据介绍,本届创交会由…...
Talk | UCSB博士生宋珍巧:基于人工智能的功能性蛋白质设计
本期为TechBeat人工智能社区第549期线上Talk。 北京时间11月22日(周三)20:00,UC Santa Barbara博士生—宋珍巧的Talk已准时在TechBeat人工智能社区开播! 她与大家分享的主题是: “基于人工智能的功能性蛋白质设计”,介绍了如何利用机器学习算…...
C++基础从0到1入门编程(四)类和对象
系统学习C 方便自己日后复习,错误的地方希望积极指正 往期文章: C基础从0到1入门编程(一) C基础从0到1入门编程(二) C基础从0到1入门编程(三) 参考视频: 1.黑马程序员匠心…...
如何有效解决UDP协议传输问题实现快速安全的文件传输
随着互联网技术的不断发展,UDP协议作为一种快速、简单的传输协议被广泛应用于文件传输领域。然而,UDP协议传输过程中也存在着一些问题,如传输速度不稳定、数据丢失等,这些问题会影响到文件传输的效率和安全性。本文将介绍UDP协议传…...
Mac下载的软件显示文件已损坏,如何解决文件已损坏问题,让文件可以正常运行
Mac下载的软件显示文件已损坏,如何解决文件已损坏问题,让文件可以正常运行 设备/引擎:Mac(11.6)/Mac Mini 开发工具:终端 开发需求:让显示已损坏的文件顺利安装到电脑 大家肯定都遇到过下载…...
实战 - 在Linux上部署各类软件
前言 为什么学习各类软件在Linux上的部署 在前面,我们学习了许多的Linux命令和高级技巧,这些知识点比较零散,同学们跟随着课程的内容进行练习虽然可以基础掌握这些命令和技巧的使用,但是并没有一些具体的实操能够串联起来这些知…...
Jenkins扩展篇-流水线脚本语法
JenkinsFile可以通过两种语法来声明流水线结构,一种是声明式语法,另一种是脚本式语法。 脚本式语法以Groovy语言为基础,语法结构同Groovy相同。 由于Groovy学习不适合所有初学者,所以Jenkins团队为编写Jenkins流水线提供一种更简…...
一个ETL流程搞定数据脱敏
数据脱敏是什么? 数据脱敏是指在数据处理过程中,通过一系列的技术手段去除或者替换敏感信息,以保护个人隐私和敏感信息的安全的过程。数据脱敏通常在数据共享、数据分析和软件测试等场景下使用,它旨在降低数据泄露和滥用的风险。…...
重生奇迹mu迹辅助什么好
主流辅助一号选手:弓箭手 智弓作为最老、最有资历的辅助职业,一直都是各类玩家的首要选择。因为智力MM提供的辅助能力都是最基础、最有效、最直观的辅助。能够减少玩家对于装备的渴求度,直接提升人物的攻防,大大降低了玩家升级打…...
【bug 回顾】上传图片超时
测试 bug 问题分析 - 上传图片超时 最近在测试上遇到一个莫名奇妙的问题,最后也没有得到具体是哪块的原因,看各位大佬有没有思路?? 一 、背景 现在我们有三台服务器,用来布两套环境。其中另外一台服务器3配置的 tom…...
避坑指南:STM32CubeMX配置基本定时器TIM中断的那些常见错误与调试技巧
STM32CubeMX定时器中断实战避坑指南:从原理到调试的完整解决方案 在嵌入式开发中,定时器中断是最基础也最常用的功能之一。许多开发者在使用STM32CubeMX配置基本定时器TIM中断时,往往会遇到各种"坑"——中断不触发、定时不准、甚至…...
终极指南:5分钟为Word添加APA第7版引用样式,告别格式烦恼
终极指南:5分钟为Word添加APA第7版引用样式,告别格式烦恼 【免费下载链接】APA-7th-Edition Microsoft Word XSD for generating APA 7th edition references 项目地址: https://gitcode.com/gh_mirrors/ap/APA-7th-Edition 在学术写作中…...
通过 Elastic MCP Server 将 Cursor 连接到生产日志
作者:来自 Elastic Jeffrey Rengifo 了解如何使用 Elastic Agent Builder MCP server 将 Cursor 连接到你的 Elastic APM 数据,这样你就可以在不离开编辑器的情况下调试生产错误,并基于真实使用数据做出 UI 决策。 前置条件 Elasticsearch 9…...
ParroT框架实战:用指令与反馈数据驯化开源大模型,打造可控翻译助手
1. 项目概述:用“提示”与“反馈”驯化大语言模型,打造专属翻译助手 在机器翻译领域,我们正处在一个激动人心的十字路口。以ChatGPT、GPT-4为代表的大语言模型(LLMs)展现出了令人惊叹的对话和翻译能力,但它…...
LSTM在时序预测中的核心原理与工业实践
1. 长短期记忆网络在序列预测中的核心价值 长短期记忆网络(LSTM)作为循环神经网络的特殊变体,在时间序列预测领域已经证明了其独特优势。与传统RNN相比,LSTM通过精心设计的门控机制,有效解决了长期依赖问题。我在多个工…...
STM32F1 HAL库实战:把PA13/PA14从SWD手里‘抢’回来做GPIO
STM32F1 HAL库实战:PA13/PA14引脚复用与SWD调试的取舍艺术 当IO资源捉襟见肘时,STM32的调试引脚往往成为开发者眼中的"备用粮仓"。PA13(SWDIO)和PA14(SWCLK)这对黄金搭档,在默认状态下被SWD调试接口独占,但当项目需要额…...
Arm架构ID寄存器解析与指令集优化实践
1. Arm架构ID寄存器概述在Arm处理器架构中,ID寄存器组是用于识别和描述处理器特性的关键系统寄存器集合。这些寄存器以只读方式提供处理器的详细实现信息,包括指令集支持、内存管理特性、调试功能等。对于系统软件开发者和性能优化工程师而言,…...
OpenClaw 101:一站式中文开发者指南与 Next.js 静态站点实践
1. 项目缘起与定位作为一名长期在开源社区和AI应用开发领域摸爬滚打的开发者,我见过太多优秀的项目因为上手门槛高、资料零散而“劝退”了无数热情的初学者。OpenClaw 这个项目就是一个典型的例子——它在 GitHub 上收获了超过 13 万颗星,热度毋庸置疑&a…...
202613读书笔记|《世界经典爱情诗100首鉴赏》——在这涛惊浪险的生活海洋之中,你的终极目的就是我的航向
202613读书笔记|《世界经典爱情诗100首鉴赏》——在这涛惊浪险的生活海洋之中,你的终极目的就是我的航向 《世界经典爱情诗100首鉴赏》许自强主编,爱情诗是诗歌王冠上的一颗璀璨明珠。它可以使人如痴如醉,忘却一切,甚至令人疯狂&a…...
COT-FM框架:机器人策略优化的条件最优传输方法
1. COT-FM框架概述:机器人策略优化的新范式 在机器人控制领域,策略优化一直面临着样本效率低、泛化能力差等核心挑战。COT-FM(Conditional Optimal Transport-Flow Matching)框架的提出,为这一领域带来了全新的解决思路…...
