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

news2024/11/6 9:29:07

本文的主要内容: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 = 10
    my_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>
  • 运行效果

我的模板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_li

app.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嵌套时,阅读性更好。

未完待续 下一期下一章

全套笔记直接地址: 请移步这里

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

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

相关文章

高通OTA升级方案介绍

高通OTA升级方案介绍 1. 高通LE OTA1.1 背景1.2 Recovery系统 2. SDX12 OTA方案3 OTA包的加密 3UK Penetration Test对于OTA升级也有严格的安全要求&#xff0c;下面是几条用例要求&#xff1a; Firmware: A sufficiently strong signing key MUST be in use. Signing keys MUS…

重要的保护: DC电源模块短路保护

重要的保护&#xff1a;BOSHIDA DC电源模块短路保护 DC电源模块是实验室和工业中非常常见的电源&#xff0c;它能够提供稳定的电压和电流输出&#xff0c;以满足各种设备和电路的需求。然而&#xff0c;如果DC电源模块没有短路保护&#xff0c;它可能会对所连接的仪器和设备造…

python-opencv划痕检测

python-opencv划痕检测 这次实验&#xff0c;我们将对如下图片进行划痕检测&#xff0c;其实这个比较有难度&#xff0c;因为清晰度太差了。 我们做法如下&#xff1a; &#xff08;1&#xff09;读取图像为灰度图像&#xff0c;进行自适应直方图均衡化处理&#xff0c;增强图…

任意文件下载漏洞(CVE-2021-44983)

简介 CVE-2021-44983是Taocms内容管理系统中的一个安全漏洞&#xff0c;可以追溯到版本3.0.1。该漏洞主要源于在登录后台后&#xff0c;文件管理栏存在任意文件下载漏洞。简言之&#xff0c;这个漏洞可能让攻击者通过特定的请求下载系统中的任意文件&#xff0c;包括但不限于敏…

SAP LU04记账更改通知单创建转储单报错:L3094 记帐修改没有份存在

解决办法&#xff1a; 使用事务码LU02&#xff0c;修改过账更改状态&#xff0c;将过账更改状态改为U&#xff0c;强制关闭 1. LU04 查找记账更改通知单号 2. 事务码LU02修改状态 这个时候再用LU04去查看的时候&#xff0c;就不会再显示了

一个ETL流程搞定数据脱敏

数据脱敏是什么&#xff1f; 数据脱敏是指在数据处理过程中&#xff0c;通过一系列的技术手段去除或者替换敏感信息&#xff0c;以保护个人隐私和敏感信息的安全的过程。数据脱敏通常在数据共享、数据分析和软件测试等场景下使用&#xff0c;它旨在降低数据泄露和滥用的风险。…

redis运维(十三) hash哈希

一 哈希 ① 定义 hash&#xff1a; 散列说明&#xff1a;key对应是值是键值对[python中的字典],其中键在redis中叫field.形如&#xff1a;value[{field1,value1},...{fieldN,valueN}],值本身又是一种键值对结构 ② 优点和缺点 wzj_height 180wzj_age 18等价 -->…

PC端页面进去先出现加载效果

自定义指令v-loading&#xff0c;只需要绑定Boolean即可 v-loading“loading” <el-table :data"list" border style"width: 100%" v-loading"loading"><el-table-column align"center" label"序号" width"5…

Talk | UCSB博士生宋珍巧:基于人工智能的功能性蛋白质设计

本期为TechBeat人工智能社区第549期线上Talk。 北京时间11月22日(周三)20:00&#xff0c;UC Santa Barbara博士生—宋珍巧的Talk已准时在TechBeat人工智能社区开播&#xff01; 她与大家分享的主题是: “基于人工智能的功能性蛋白质设计”&#xff0c;介绍了如何利用机器学习算…

Course1-Week1:机器学习简介

Course1-Week1&#xff1a;机器学习简介 文章目录 Course1-Week1&#xff1a;机器学习简介1. 课程简介1.1 课程大纲1.2 Optional Lab的使用 (Jupyter Notebooks)1.3 欢迎参加《机器学习》课程 2. 机器学习简介2.1 机器学习定义2.2 有监督学习2.3 无监督学习 3. 线性回归模型3.1…

ssm+vue的物资物流系统的设计与实现(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的物资物流系统的设计与实现&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体…

SSM人事请假签到管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 SSM人事请假签到管理系统是一套完善的完整人事请假薪酬加班管理&#xff0c;结合SSM框架完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统…

巫溪家和计划——“平安快乐幸福家”宣传活动

8月&#xff0c;在重庆市婚姻收养登记管理中心的指导下&#xff0c;巫溪县民政局婚姻登记处、巫溪县同心社会工作服务中心在通城镇夏布坪海棠园会议室开展了“家和童行过暑假&#xff0c;平安快乐幸福家”安全教育活动&#xff0c;围绕防溺水安全、交通安全、消防安全、防拐怪防…

Linux中df命令使用

在Linux中&#xff0c;df命令用于显示磁盘空间的使用情况。它的基本语法如下&#xff1a; df [选项] [文件或目录]这个命令可以用来查看当前系统上各个磁盘分区的使用情况。如果没有指定文件或目录&#xff0c;则所有当前被挂载的文件系统的可用空间将被显示。 df命令的一些常…

促进材料基因工程基础理论、前沿技术和关键装备的发展和应用,第七届材料基因工程高层论坛将于12月重庆举办,龙讯旷腾出席会议

为了进一步促进材料基因工程基础理论、前沿技术和关键装备的发展和应用&#xff0c;加强国际交流&#xff0c;加速我国新材料的研发和应用&#xff0c;由中国材料研究学会、西部科学城重庆高新区管理委员会主办&#xff0c;重庆大学、北京科技大学、北京云智材料大数据研究院等…

SAP 锁机制及创建与使用介绍

一、SAP为什么要设置锁&#xff1a; 1&#xff0c;保持数据的一致性 如果几个用户要访问同样的资源&#xff0c;需要找到一种同步访问的方法去保持数据的一致性。比如说&#xff0c;在航班预订系统中&#xff0c;需要检查还有没有空座位&#xff0c;当检查的时候&#xff0c;你…

欧拉操作系统下离线安装字体的操作步骤

背景 某 Web 应用部署到欧拉操作系统后&#xff0c;应用中导出的 PDF 文件中文全部显示乱码&#xff0c;原因是字体缺失&#xff0c;但是目标系统上并没有联网&#xff0c;必须找到字体的离线安装包。 CSDN 上还有40个积分&#xff0c;下载了两个相关的资源后&#xff0c;目标…

千兆光模块和万兆光模块的供应链管理

随着网络通信技术的不断发展&#xff0c;千兆光模块和万兆光模块已逐渐成为现代网络建设中不可缺少的组成部分。它们在云计算、数据中心、大规模机房以及企业内部网络等领域广泛应用&#xff0c;已经成为大家熟知的产品。 千兆光模块和万兆光模块的工作原理基本相同&#xff…

【AI】行业消息精选和分析(11月23日)

今日动态 1、Sam Altman 重掌 CEO&#xff0c;OpenAI 权力斗争正式「落幕」 2、重磅好消息&#xff1a;语音 ChatGPT 现已向全用户开放 3、NVIDIA 与基因泰克合作&#xff0c;利用生成式 AI 加速药物发现 4、 英伟达Q3营收同比增长206%至181亿美元 黄仁勋&#xff1a;生成式AI时…

【第一部分:概述】ARM Realm Management Monitor specification

目录 概述机密计算系统软件组成MonitorRealmRealm Management Monitor (RMM)Virtual Machine (VM)HypervisorSecure Partition Manager (SPM)Trusted OS (TOS)Trusted Application (TA) Realm Management Monitor 参考文献 概述 RMM是一个软件组件&#xff0c;它构成了实现ARM…