Flask模版详解

news2024/12/25 10:51:38

Flask模版详解

  • 概述
  • Jinja2模板引擎
    • 渲染模版的步骤
    • 变量
    • 控制结构
    • 自定义错误页面
    • 链接
    • 静态文件

概述

模板是一个包含响应文本的文件,其中包含用占位变量表示的动态部分,其具体值只在请求的上下文中才能知道。使用真实值替换变量,再返回最终得到的响应字符串,这一过程称为渲染。为了渲染模板,Flask 使用了一个名为 Jinja2 的强大模板引擎

形式最简单的 Jinja2 模板就是一个包含响应文本的文件,例如:

<h1>Hello, {{ name }}!</h1>

Jinja2模板引擎

渲染模版的步骤

1、前端创建模版

默认情况下,Flask 在程序文件夹中的 templates 子文件夹中寻找模板。例如把前面定义的模板保存在templates 文件夹中,命名为index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
</head>
<body>
<h1>Hello, {{ name }}!</h1>
</body>
</html>

2、后端渲染模版

@app.route('/')
def index():
    name = "dahezhiquan"
    return render_template('index.html', name=name)

Flask 提供的 render_template 函数把 Jinja2 模板引擎集成到了程序中。render_template 函数的第一个参数是模板的文件名。随后的参数都是键值对,表示模板中变量对应的真实值。在这段代码中,第二个模板收到一个名为 name 的变量

左边的“name”表示参数名,就是模板中使用的占位符;右边的“name”是当前作用域中的变量,表示同名参数的值

3、运行程序,查看模版渲染效果

image.png

变量

在模板中使用的{{ name }}结构表示一个变量,它是一种特殊的占位符,告诉模板引擎这个位置的值从渲染模板时使用的数据中获取

Jinja2 能识别所有类型的变量,甚至是一些复杂的类型,例如列表、字典和对象。在模板中使用变量的一些示例如下:

<!-- 从字典中获取值 -->
<p>A value from a dictionary: {{ mydict['key'] }}.</p>

<!-- 从列表中获取值 -->
<p>A value from a list: {{ mylist[3] }}.</p>

<!-- 从列表中获取值,使用变量作为索引 -->
<p>A value from a list, with a variable index: {{ mylist[myintvar] }}.</p>

<!-- 调用对象的方法 -->
<p>A value from an object's method: {{ myobj.somemethod() }}.</p>

同时还可以使用过滤器修改变量,过滤器名添加在变量名之后,中间使用竖线分隔,例如,下述模板以首字母大写形式显示变量 name 的值:

Hello, {{ name|capitalize }}

Jinja2 提供的部分常用过滤器:

  • safe:标记变量为安全,使得它们不会被转义。例如:{{ my_html_content | safe }}
  • capitalize:将字符串的首字母大写。例如:{{ my_string | capitalize }}
  • lower:将字符串转换为小写。例如:{{ my_string | lower }}
  • upper:将字符串转换为大写。例如:{{ my_string | upper }}
  • title:将字符串中每个单词的首字母大写。例如:{{ my_string | title }}
  • trim:除字符串两侧的空白字符。例如:{{ my_string | trim }}
  • striptags:移除所有 HTML 标签,并仅保留纯文本内容

safe 过滤器值得特别说明一下。默认情况下,出于安全考虑,Jinja2 会转义所有变量。例如,如果一个变量的值为 ‘<h1>Hello</h1>’,Jinja2 会将其渲染成’&lt;h1&gt;Hello&lt;/h1&gt;',浏览器能显示这个 h1 元素,但不会进行解释。很多情况下需要显示变量中存储的 HTML 代码,这时就可使用 safe 过滤器。千万别在不可信的值上使用 safe 过滤器,例如用户在表单中输入的文本。

控制结构

Jinja2 提供了多种控制结构,可用来改变模板的渲染流程,例如:

{% if user %}
    Hello, {{ user }}!
{% else %}
    Hello, stranger!
{% endif %}

另一种常见需求是在模板中渲染一组元素。下例展示了如何使用 for 循环实现这一需求:

<ul>
{% for comment in comments %}
    <li>{{ comment }}</li>
{% endfor %}
</ul>

Jinja2 还支持宏。宏类似于 Python 代码中的函数。例如:

{% macro render_comment(comment) %}
    <li>{{ comment }}</li>
{% endmacro %}

<ul>
{% for comment in comments %}
    {{ render_comment(comment) }}
{% endfor %}
</ul>

在这个模板中,{% macro render_comment(comment) %} 定义了一个宏,它接受一个名为 comment 的参数,并返回一个 <li> 标签,其中包含评论内容。{% endmacro %} 表示宏定义的结束。

然后,在循环中,{% for comment in comments %} 遍历评论列表,并对每个评论调用 render_comment 宏来生成相应的 HTML。每次循环迭代时,宏将被展开,生成一个包含评论内容的列表项,并将其插入到 <ul> 中。

这种使用宏的方式可以使模板更具可重用性和可维护性,特别是当需要在多个地方使用相同的 HTML 结构时。

需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有模板中,以避免重复:

{% include 'common.html' %}

另一种重复使用代码的强大方式是模板继承,它类似于 Python 代码中的类继承。首先,创建一个名为 base.html 的基模板:

<html lang="zh-CN">
<head>
    {% block head %}
        <title>{% block title %}{% endblock %} - My Application</title>
    {% endblock %}
</head>
<body>
    {% block body %}
    {% endblock %}
</body>
</html>

在这个模板中,{% block head %} {% block body %} 标记定义了两个可替换的块,它们分别用于定义页面头部和主体内容

下面这个示例是基模板的衍生模板:

{% extends "base.html" %}

{% block title %}
    Index
{% endblock %}

{% block head %}
    {{ super() }}
    <style>
    </style>
{% endblock %}

{% block body %}
    <h1>Hello, World!</h1>
{% endblock %}

在这个子模板中,使用了 {% extends "base.html" %} 来继承基础模板。然后,重写了 title 块,将页面标题设置为 “Index”。接着,重写了 head 块,在原有的基础上使用了 super() 函数来调用基础模板中定义的内容,并添加了特定页面的样式。最后,重写了 body 块,定义了页面的主体内容

image.png

自定义错误页面

如果你在浏览器的地址栏中输入了不可用的路由,那么会显示一个状态码为 404 的错误页面
像常规路由一样,Flask 允许程序使用基于模板的自定义错误页面。最常见的错误代码有两个:404,客户端请求未知页面或路由时显示;500,有未处理的异常时显示

1、编写视图代码

@app.errorhandler(404)
def page_not_found(e):
    return render_template('errors/404.html'), 404


@app.errorhandler(500)
def internal_server_error(e):
    return render_template('errors/500.html'), 500

2、编写错误模版代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>404</title>
  </head>
  <body>
    <h1>404</h1>
  </body>
</html>

3、此时访问一个不存在的URL,会呈现自定义的404模版页面

image.png

链接

任何具有多个路由的程序都需要可以连接不同页面的链接,例如导航条。

在模板中直接编写简单路由的 URL 链接不难,但对于包含可变部分的动态路由,在模板中构建正确的 URL 就很困难。而且,直接编写 URL 会对代码中定义的路由产生不必要的依赖关系。如果重新定义路由,模板中的链接可能会失效。

为了避免这些问题,Flask 提供了 url_for() 辅助函数,它可以使用程序 URL 映射中保存的信息生成 URL。

url_for('index') 得到的结果是 /。调用 url_for('index', _external=True) 返回的则是绝对地址,例如:http://127.0.0.1:5000/

使用 url_for() 生成动态地址时,将动态部分作为关键字参数传入。例如:

url = url_for('index', name='john', _external=True)

上述代码的返回结果是,http://127.0.0.1:5000/index?name=john

静态文件

Web 程序不是仅由 Python 代码和模板组成。大多数程序还会使用静态文件,例如HTML代码中引用的图片、JavaScript 源码文件和 CSS

默认设置下,Flask 在程序根目录中名为 static 的子目录中寻找静态文件。如果需要,可在 static 文件夹中使用子文件夹存放文件

1、在项目的static文件夹中上传icon网页图标文件

image.png

2、在base.html中使用favicon.ico

<html lang="zh-CN">
<head>
    {% block head %}
        <title>{% block title %}{% endblock %} - My Application</title>
    {% endblock %}
    <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
    <link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
</head>
<body>
    {% block body %}
    {% endblock %}
</body>
</html>

3、icon图标设置成功

image.png

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

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

相关文章

Android4.4真机移植过程笔记(三)

如果文章字体看得不是很清楚&#xff0c;大家可以下载pdf文档查看&#xff0c;文档已上传&#xff5e;oo&#xff5e; 7、安装加密APK 需要修改文件如下&#xff1a; 相对Android4.2改动还是蛮大的&#xff0c;有些文件连路径都变了: //Android4.2 1、frameworks/native/libs…

如何运用结构化思维来规划个人发展

结构化思维不仅在工作中非常有用&#xff0c;在日常生活中同样可以发挥巨大作用。无论是解决家庭琐事、规划个人发展&#xff0c;还是做出重要决策&#xff0c;结构化思维都能帮助我们更有条理地思考和行动。 一、解决生活中的问题 生活中总会遇到各种各样的问题&#xff0…

Unity+Shader入门精要-1. 入门shader

今天开始正式整合学习的shader内容。 Simple Shader 主要介绍了大概的shader格式。 Shader "Unity Sgaders Book/Chapter 5/Simple Shader" //shader名 {Properties{//声明color类型的属性_Color("Color Tint", Color) (1.0,1.0,1.0,1.0)}SubShader{Pa…

【SpringBoot】数据脱敏

文章目录 什么是数据脱敏JsonSerialize自定义Jackson注解定制脱敏策略定制JSON序列化实现脱敏工具类 定义Person类&#xff0c;对其数据脱敏模拟接口测试总结 什么是数据脱敏 数据脱敏&#xff0c;也称为数据的去隐私化或数据变形&#xff0c;是一种技术手段&#xff0c;用于对…

tcp inflight 守恒算法的自动收敛

inflight 守恒算法看起来只描述理想情况&#xff0c;现实很难满足&#xff0c;是这样吗&#xff1f; 从 reno 到 bbr&#xff0c;无论哪个算法都在描述理想情况&#xff0c;以 reno 和 bbr 两个极端为例&#xff0c;它们分别描述两种理想管道&#xff0c;reno 将 buffer 从恰好…

【C++庖丁解牛】C++11---新的类的功能 | 可变参数模板

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 1.新的类功能1.1 默认成员…

浏览器预加载器如何使页面加载速度更快

预加载器&#xff08;也称为推测或前瞻预解析器&#xff09;可能是浏览器性能有史以来最大的改进。 那么什么是预加载器以及它如何提高性能呢&#xff1f; 浏览器如何加载网页 网页充满了依赖关系——在下载相关的CSS之前页面无法开始渲染&#xff0c;然后当遇到脚本时HTML解…

零基础该如何自学linux运维?

零基础该如何自学linux运维&#xff1f;以下是建议帮助你入门Linux运维的一些建议。 一、自学建议&#xff1a; 理解基础概念&#xff1a;首先&#xff0c;你需要对Linux操作系统的基本概念有所了解&#xff0c;包括文件系统、用户权限、进程管理等。安装Linux系统&#xff1…

若依前后端部署系统--详细附图

一、后端部署 1、在ruoyi项目的Maven中的生命周期下双击package.bat打包Web工程&#xff0c;生成jar包文件。 提示打包成功 2、多模块版本会生成在ruoyi/ruoyi-admin模块下target文件夹,我们打开目录ruoyi-admin/taget&#xff0c;打开cmd&#xff0c;运行java -jar jar包名称…

【C语言进阶】程序编译中的预处理操作

&#x1f4da;作者简介&#xff1a;爱编程的小马&#xff0c;正在学习C/C&#xff0c;Linux及MySQL.. &#x1f4da;以后会将数据结构收录为一个系列&#xff0c;敬请期待 ● 本期内容讲解C语言中程序预处理要做的事情 目录 1.1 预处理符号 1.2 #define 1.2.1 #define定义标识…

【Docker学习】docker stats

命令&#xff1a; docker container stats 描述&#xff1a; 显示容器资源使用的状态&#xff08;实时&#xff09; 用法&#xff1a; docker container stats [OPTIONS] [CONTAINER...] 别名&#xff1a; docker stats(docker的一些命令可以简写&#xff0c;docker stats就等同…

Odoo17开发环境搭建

1.先下载godoo17_20240227_02.zip压缩包&#xff0c;里面包含了项目用到的所有的插件了&#xff0c;直接使用这个包即可。 下载地址&#xff1a;https://download.csdn.net/download/java173842219/89242257 2.解压该压缩包&#xff0c;目录如下&#xff1a; 3.下载pycharm并…

如何保证Redis双写一致性?

目录 数据不一致问题 数据库和缓存不一致解决方案 1. 先更新缓存&#xff0c;再更新数据 该方案数据不一致的原因 2. 先更新数据库&#xff0c;再更新缓存 3. 先删除缓存&#xff0c;再更新数据库 延时双删 4. 先更新数据库&#xff0c;再删除缓存 该方案数据不一致的…

声明式事务(@Transactional)使用时需要注意的坑

前言 上两篇文章已经详细分析了申明式事务的实现原理&#xff0c;知道了底层原理之后&#xff0c;现在就可以开始使用申明式事务去简化我们的代码了。但是在使用Transactional注解的时候也会经常遇到一些问题&#xff0c;有些问题不仔细测试观察的话还不容易发现&#xff0c;比…

Windows vbs脚本定时给焦点窗口发送消息

直接上脚本代码,你们可以自己看着改 MsgInputbox("message1") Msg1Inputbox("message2") numInputbox("number")a1 bnumset wshshellCreateObject("wscript.shell") 创建Windows的shell对象打开shell窗口 wscript.sleep 5000for ia t…

vue本地调试devtools

一、谷歌浏览器加载扩展程序 二、把解压的压缩包添加即可&#xff0c;重启浏览器 三、启动前端本地项目&#xff0c;即可看到Vue小图标

Linux|awk 特殊模式“BEGIN 和 END”

引言 在本文[1]&#xff0c;我们将介绍Awk的更多特性&#xff0c;特别是两个特殊的模式&#xff1a;BEGIN和END。 这些独特的功能在我们努力扩展和深入探索构建复杂Awk操作的多种方法时&#xff0c;将大有裨益。 实例 让我们从Awk系列的开篇回顾开始&#xff0c;回想一下&#…

SSL证书一般是怎么收费的?

SSL证书的费用通常按照以下几个因素决定&#xff1a; 1. 证书类型&#xff1a; - 域名验证&#xff08;DV&#xff09;证书&#xff1a;这是最基本的类型&#xff0c;仅验证域名所有权&#xff0c;费用一般在几十到几百之间. - 组织验证&#xff08;OV&#xff09;证书&#xf…

【触摸案例-手势解锁案例-九宫格 Objective-C语言】

一、手势解锁案例,九宫格,我们先来分析一下怎么实现: 首先呢,我们先来运行一下, 这一块儿,上面的这九个东西,肯定是要有一个九宫格的一个算法的问题,然后呢,上边的这九个小圆圈儿,这是什么东西,Button,为什么是Button,因为可以点,是吗,就因为这个?实际上,你用…

LeetCode55:跳跃游戏

题目描述 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 解题思想 每次…