(十一)Flask模板引擎jinja2

news2025/1/20 19:12:11

模板引擎Jinja2

一、简介及基本使用:

Flask使用Jinja2作为默认的模板引擎。Jinja2是一个功能强大且易于使用的模板引擎,它允许我们在HTML中嵌入Python代码,并通过将模板和数据进行渲染来生成动态内容。

实战之在Flask中使用Jinja2模板引擎:

  1. 在Flask应用程序的根目录下创建一个名为templates的文件夹,用于存放模板文件。

  2. 创建一个名为index.html的模板文件,在其中可以使用Jinja2语法来插入动态内容,即使用双花括号{{ }}来插入Jinja2表达式,这些表达式将在渲染模板时被替换为实际的值。

    <!DOCTYPE html>
    <html>
    <head>
        <title>Flask Template Engine</title>
    </head>
    <body>
        <h1>Welcome to {{ title }}</h1>
        <p>{{ message }}</p>
    </body>
    </html>
    
  3. 在Flask应用程序中导入render_template函数,并在路由函数中调用该函数以渲染模板并返回响应。

    from flask import Flask, render_template
    
    app = Flask(__name__)
    
    
    @app.route('/')
    def home():
        title = 'Flask Template Engine'
        message = 'Hello, World!'
        return render_template('index.html', title=title, message=message)
    
    
    if __name__ == '__main__':
        app.run()
    
    

    在视图函数中,定义了titlemessage两个变量,并将其传递给render_template()函数。

    render_template()函数接收模板名称作为第一个参数,以及可选的关键字参数用于传递给模板的数据。

    render_template()函数将根据模板文件中的Jinja2语法进行渲染,并返回渲染后的HTML内容作为响应发送给客户端。

通过使用Jinja2模板引擎,可以将静态HTML页面与动态生成的内容结合起来,实现更灵活、可维护和可重用的视图层逻辑。在模板中,可以使用条件语句、循环语句、过滤器等功能,对数据进行处理和展示,从而创建出更丰富的用户界面。

先简单将一讲Jinja2模板引擎的一些特性和用法【下面都会详细讲解~】:

  1. 模板语法:Jinja2使用{{ ... }}来标记表达式,表示将变量插入到模板中。例如,{{ name }}将会在模板中显示变量name的值。而使用{% ... %}来标记控制结构和语句,如条件语句、循环语句等。

  2. 变量:可以在模板中使用变量来动态地渲染内容。通过传递变量给模板进行渲染,例如:render_template('index.html', name=name)。在模板中,可以使用{{ variable_name }}语法来插入变量的值。

  3. 过滤器:Jinja2提供了许多内置的过滤器函数,用于对变量进行处理和格式化。例如,{{ name|capitalize }}会将变量name的首字母大写。还可以自定义过滤器函数,使用@app.template_filter()装饰器注册为模板过滤器。

  4. 控制结构:Jinja2支持各种控制结构,如if语句、循环语句和宏。通过使用{% if ... %}...{% endif %}来实现条件语句,使用{% for ... in ... %}...{% endfor %}来实现循环语句,以及使用{% macro ... %}...{% endmacro %}来定义宏。

  5. 继承:Jinja2允许模板之间进行继承,以提高代码的可重用性和可维护性。通过使用{% extends ... %}指令,一个模板可以继承另一个模板,并在其中使用{% block ... %}...{% endblock %}来替换或扩展基础模板中的内容。

  6. 模板包含:Jinja2支持模板包含,允许将一个模板嵌入到另一个模板中。通过使用{% include ... %}指令,可以在模板中引用其他模板文件,实现代码的复用。

  7. 自定义全局变量和函数:可以在Flask应用中注册自定义的全局变量和函数,使其在所有模板中可用。通过使用app.jinja_env.globals['variable_name'] = value来注册全局变量【需要注意,在注册模板全局变量时,建议将其放置在一个在应用启动时运行的函数(如before_first_request装饰的函数)中,以确保全局变量在所有请求中都可用】;使用@app.template_global()装饰器来注册全局函数。

二、支持的Python数据类型:

Flask的Jinja2模板引擎支持以下Python数据类型:

  1. 字符串(String):用于表示文本数据。
  2. 整数(Integer):用于表示整数值,如1、2、3等。
  3. 浮点数(Float):用于表示带有小数部分的数值,如3.14、2.5等。
  4. 布尔值(Boolean):用于表示真或假的值,True或False。
  5. 列表(List):用于表示有序的集合,可以包含任意类型的元素。例如:[1, 2, 'a', True]
  6. 元组(Tuple):类似于列表,但是是不可变的,也就是说不能修改元素的值。例如:(1, 2, 'a', True)
  7. 字典(Dictionary):用于表示键值对的集合,其中每个元素由一个键和一个对应的值组成。例如:{'name': 'John', 'age': 25}
  8. 集合(Set):用于表示无序且唯一的元素集合,不允许重复的元素。例如:{'apple', 'banana', 'orange'}

除了上述基本数据类型之外,Jinja2模板还支持使用过滤器对数据进行处理和格式化,以及使用控制结构如条件语句和循环语句来控制模板的渲染流程。

需要注意的是,Jinja2模板引擎并不限制使用上述数据类型,可以在模板中使用任何Python支持的数据类型。如果有自定义的类或对象,也可以将其传递给模板,并在模板中访问其属性或调用其方法。

(1)实战在模板中使用Python常见的基本数据类型:

from flask import Flask, render_template

app = Flask(__name__)


@app.route("/index", methods=['GET', 'POST'])
def index():
    context = {
        'k1': 123,
        'k2': [11, 22, 33],
        'k3': {'name': 'oldboy', 'age': 84}
    }

    return render_template('index.html', **context)


if __name__ == '__main__':
    app.run()

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>{{ k1 }}</h1>
    <h1>{{k2.0}}  {{k2[0]}}</h1>
    <h1>{{k3.name}}  {{k3['name']}}  {{k3.get('name', 888)}}</h1>
</body>
</html>

在这里插入图片描述

(2)实战在模板中使用匿名函数:

from flask import Flask, render_template

app = Flask(__name__)


@app.route("/index", methods=['GET', 'POST'])
def index():
    context = {
        'k1': 123,
        'k2': [11, 22, 33],
        'k3': {'name': 'oldboy', 'age': 84},
        'k4': lambda x: x+1
    }

    return render_template('index.html', **context)


if __name__ == '__main__':
    app.run()

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>{{ k1 }}</h1>
    <h1>{{k2.0}}  {{k2[0]}}</h1>
    <h1>{{k3.name}}  {{k3['name']}}  {{k3.get('name', 888)}}</h1>
    <h1>{{k4(66)}}</h1>
</body>
</html>

在这里插入图片描述

(3)实战在模板中使用普通函数:

from flask import Flask, render_template

app = Flask(__name__)


def gen_input(value):
    return "<input value='%s' />" %value


@app.route("/index", methods=['GET', 'POST'])
def index():
    context = {
        'k1': 123,
        'k2': [11, 22, 33],
        'k3': {'name': 'oldboy', 'age': 84},
        'k4': lambda x: x+1,
        'k5': gen_input
    }

    return render_template('index.html', **context)


if __name__ == '__main__':
    app.run()

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>{{ k1 }}</h1>
    <h1>{{k2.0}}  {{k2[0]}}</h1>
    <h1>{{k3.name}}  {{k3['name']}}  {{k3.get('name', 888)}}</h1>
    <h1>{{k4(66)}}</h1>

    <h1>{{k5(99)}}</h1>
</body>
</html>

如果不加 | safe,就直接显示字符串而不是input标签。这是Flask防止xss攻击。默认用户输入都是不安全的。

在这里插入图片描述

两种解决方法:

  • 一种是前端加 | safe
  • 一种是后端使用markup。
    <h1>{{k5(99) | safe}}</h1>
from flask import Flask, render_template, Markup

app = Flask(__name__)


def gen_input(value):
    # return "<input value='%s' />" %value
    return Markup("<input value='%s' />" %value)

三、template_global()装饰器:

问题引入:

当我们在每一个模板里都想自定义一些函数: 如果每一个视图里都手动加,是不是太麻烦了!

解决方法:

  • 这就引出了template_global()装饰器,使用它装饰的函数在每一个模板里都可以直接使用!!!

    template_global()装饰器用于将一个函数注册为全局模板变量。被该装饰器修饰的函数可以在所有的模板中使用,并且不需要在每个视图函数中都传递一遍。

@app.template_global()
def sb(a1, a2):
    return a1 + a2
<body>
	<h1>{{sb(1,2)}}</h1>
</body>

需要注意的是,在使用template_global装饰器时,函数名就是全局模板变量的名称。因此,在模板中调用全局模板变量时,直接使用函数名即可。

通过使用template_global装饰器,我们可以方便地注册全局模板变量,提高代码的重用性和可维护性,并简化视图函数与模板之间的数据传递过程。

四、template_filter装饰器:

  1. 常规用法:

    template_filter用于将一个函数注册为模板过滤器。被该装饰器修饰的函数可以在模板中通过过滤器的名称进行调用,并对数据进行处理和格式化。

    实战使用:

from flask import Flask, render_template

app = Flask(__name__)


@app.template_filter()
def reverse_string(string):
    return string[::-1]


@app.route('/')
def home():
    name = 'John Doe'
    return render_template('index.html', name=name)


if __name__ == '__main__':
    app.run()

在上述示例中,定义了一个名为reverse_string的函数,并使用template_filter()装饰器将其注册为模板过滤器。这个函数接受一个字符串参数,并返回反转后的字符串。

home视图函数中,将用户的姓名传递给模板,并在模板中使用{{ name|reverse_string }}来调用模板过滤器。这样,在模板中会自动将用户的姓名进行反转处理。

在使用template_filter装饰器时,函数名就是模板过滤器的名称。因此,在模板中调用模板过滤器时,使用|管道符号将变量与过滤器名称分隔开。

在这里插入图片描述

  1. 技巧使用:
from flask import Flask, render_template

app = Flask(__name__)


@app.template_filter()
def add_all(a1, a2, a3):
    return a1 + a2 + a3


@app.route('/')
def home():
    return render_template('index.html')


if __name__ == '__main__':
    app.run()
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <h1>{{ 1 | add_all(2,3) }}</h1>
</body>
</html>

在这里插入图片描述

五、Flask模板的继承:

Flask模板的继承是一种在多个模板中共享相同布局和结构的方式。通过使用模板的继承,我们可以定义一个基础模板,其中包含通用的 HTML 结构和样式,并在其他模板中继承这个基础模板,只需专注于特定内容的定义。

实战讲解:

base.html(基础模板):

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <header>
        {% block header %}
            <h1>Welcome to my website!</h1>
        {% endblock %}
    </header>

    <main>
        {% block content %}{% endblock %}
    </main>

    <footer>
        {% block footer %}
            &copy; 2023 My Website - GuHanZhe. All rights reserved.
        {% endblock %}
    </footer>
</body>
</html>

home.html(继承自base.html):

{% extends 'base.html' %}

{% block title %}
    Home Page
{% endblock %}

{% block content %}
    <h2>Welcome to the Home Page!</h2>
    <p>Content specific to the home page goes here.</p>
{% endblock %}

about.html(继承自base.html):

{% extends 'base.html' %}

{% block title %}
    About Page
{% endblock %}

{% block content %}
    <h2>About Us</h2>
    <p>Content specific to the about page goes here.</p>
{% endblock %}

在上述示例中,base.html 是一个基础模板,定义了整个网页的结构和通用元素。其他模板(home.html 和 about.html)通过 {% extends 'base.html' %} 指令继承自 base.html,并可以使用 {% block %} 块来替换或扩展基础模板中的内容。

每个子模板都可以通过 {% block %} 块来定义自己特定的内容,这些块将在渲染时插入到相应的位置。例如,在 home.html 中的 {% block content %} 块中定义了特定于首页的内容。

通过使用模板继承,可以避免在每个模板中重复编写相同的 HTML 结构和样式,提高代码的可重用性和可维护性。

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

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

相关文章

GDS 命令的使用 srvctl service TAF application continuity

文档中prim and stdy在同一台机器上&#xff0c;不同机器需要添加address list TAF ENABLED GLOBAL SERVICE in GDS ENVIRONMNET 12C. (Doc ID 2283193.1)​编辑To Bottom In this Document Goal Solution APPLIES TO: Oracle Database - Enterprise Edition - Version 12.1.…

操作系统(五)文件系统和I/O系统

文章目录 前言文件系统文件系统和文件文件描述符目录、文件别名和文件系统分层文件系统目录实现文件别名名字解析&#xff08;路径遍历&#xff09;文件系统挂载文件系统种类 虚拟文件系统文件缓存和打开文件打开文件 文件分配空闲空间管理和冗余磁盘阵列RAID空闲空间管理冗余磁…

小程序游戏、App游戏与H5游戏:三种不同的游戏开发与体验方式

在当今数字化的时代&#xff0c;游戏开发者面临着多种选择&#xff0c;以满足不同用户群体的需求。小程序游戏、App游戏和H5游戏是三种流行的游戏开发和发布方式&#xff0c;它们各自具有独特的特点和适用场景。 小程序游戏&#xff1a;轻巧便捷的社交体验 小程序游戏是近年来…

为什么都说学医的转行网络安全行业更容易些?

网络系统坏了&#xff0c;被入侵破坏了&#xff0c;找安全工程师防护修补。如果没有修好&#xff0c;我可以不给钱&#xff0c;再找一家能修好的。但是看病就不一样了&#xff0c;就算医生没有给我治好病&#xff0c;也照样要收医疗费。 这样的类比乍一听上去好像挺有道理&…

解析:什么是生成式AI?与其他类型的AI有何不同?

原创 | 文 BFT机器人 快速浏览一下头条新闻&#xff0c;你会发现生成式AI似乎无处不在。事实上&#xff0c;一些新闻标题甚至可能是通过生成式AI编写的&#xff0c;例如OpenAI旗下的ChatGPT&#xff0c;这个聊天机器人已经展现出了生成看起来像人类所写文本的惊人能力。 当人们…

蓝桥杯每日一题2023.11.16

蓝桥杯大赛历届真题 - C 语言 B 组 - 蓝桥云课 (lanqiao.cn) 题目描述 对于此代码&#xff0c; 注释解释如下&#xff1a;答案&#xff1a;f(a,k1,m-j,b)&#xff1b; 在这里插入代码片#include <stdio.h> #define N 6 #define M 5 #define BUF 1024 void f(int a[], in…

市场研究报告:量子计算将颠覆银行业!

&#xff08;图片来源&#xff1a;网络&#xff09; 量子银行将对金融体系产生重大影响&#xff0c;它在量子计算和区块链的基础上建立了一个更快的支付机制&#xff0c;并且通过消除传统点对点支付中常见的中间人&#xff0c;降低了运营成本。 量子计算及其运作机制 中东地区…

【人工智能实验】遗传算法求解旅行商问题 golang

人工智能经典问题旅行商求解 使用遗传算法求解&#xff0c;算法流程如下&#xff1a; 读取所有的城市坐标&#xff0c;记作集合initCitys生成popSize个种群&#xff0c;记为pops取出种群中适应度最高的&#xff0c;记作rank0使用轮盘算法&#xff0c;从rank0中选出eliteSize个…

Redis分布式锁(中)

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 我们在不久前介绍了Spr…

【场景】高并发解决方案

文章目录 1. 硬件2. 缓存2.1 HTTP缓存2.1.1 浏览器缓存2.1.2 Nginx缓存2.1.3 CDN缓存 2.2 应用缓存 3 集群4. 拆分4.1 应用拆分&#xff08;分布式、微服务&#xff09;4.2 数据库拆分 5. 静态化6. 动静分离7. 消息队列8. 池化8.1 对象池8.2 数据库连接池8.3 线程池 9. 数据库优…

酷开系统 酷开科技,将家庭娱乐推向新高潮

在当今数字化时代&#xff0c;家庭娱乐已经成为人们日常生活中不可或缺的一部分。如果你厌倦了传统的家庭娱乐方式&#xff0c;想要一种全新的、充满惊喜的娱乐体验&#xff0c;那么&#xff0c;不妨进入到酷开科技的世界&#xff0c;作为智能电视行业领军企业&#xff0c;酷开…

Git常用操作-MD

文章目录 1. 本地创建分支&#xff0c;编写代码&#xff0c;提交本地分支到远程仓库2. 提交本地代码到本地仓库3. 提交本地代码到本地dev分支4. 提交本地dev分支到远程仓库5. 本地dev分支拉取远程master分支&#xff0c;并将master分支内容合并到本地dev6. 同义命令7. 撤销上次…

Codeforces Round 908 (Div 2——AB)

A. Secret Sport 题目 AB二人玩游戏&#xff0c;每一局&#xff08;plays&#xff09;游戏会有一个获胜者&#xff0c;首先获胜X局&#xff08;play&#xff09;的玩家得一分&#xff08;赢得一轮sets&#xff09;。率先获得Y分的玩家获得最终胜利。 给你整场游戏的每局&…

Spring Boot使用EhCache完成一个缓存集群

在上一篇在SpringBoot中使用EhCache缓存&#xff0c;我们完成了在Spring Boot中完成了对EhCaChe的使用&#xff0c;这篇&#xff0c;我们将对EhCache的进一步了解&#xff0c;也就是搭建一个EhCache的缓存集群。 集群 在搭建一个EhCache的时候&#xff0c;我们需要先了解&…

areadetector ADURL模块应用在面探测控制的初步应用

本章中讨论了使用ADURL控制面探测器Lambda的过程&#xff1a; ADURL的使用请见&#xff1a; EPICS -- areaDetector URL驱动程序-CSDN博客 需要启动一个ADURL的IOC程序&#xff0c;并且设置相关的插件中参数的值&#xff1a; # st.cm < envPaths < st_base.cmddbpf 1…

WorkPlus即时通讯app支持多种信创环境组合运行

在信息技术领域&#xff0c;国产信创技术的快速发展为企业带来了更多的选择和机会。在此背景下&#xff0c;WorkPlus作为一款全方位的移动数字化平台&#xff0c;全面支持国产信创操作系统、芯片和数据库&#xff0c;并且全面兼容鸿蒙操作系统。这一优势使得WorkPlus成为了企业…

企业数据备份应该怎么操作?应该知道的四种备份方法

​企业数据备份对于保护最重要的资产至关重要。在面对不断增加的安全威胁时&#xff0c;很多企业都感到无从下手&#xff0c;不知如何保护关键业务数据。通过采用正确的数据备份方法&#xff0c;可以成为确保企业数据安全的最有效手段。因此&#xff0c;不论您是个人还是在职人…

第二证券:今日投资前瞻:小米汽车引关注 全球风光有望持续高速发展

昨日&#xff0c;两市股指盘中轰动上扬&#xff0c;深成指、创业板指一度涨超1%。到收盘&#xff0c;沪指涨0.55%报3072.83点&#xff0c;深成指涨0.72%报10077.96点&#xff0c;创业板指涨0.53%报2015.36点&#xff0c;北证50指数涨2.64%&#xff1b;两市算计成交9900亿元&…

亚马逊云科技云存储服务指南

文章作者&#xff1a;Libai 高效的云存储服务对于现代软件开发中的数据管理至关重要。亚马逊云科技云存储服务提供了强大的工具&#xff0c;可以简化工作流程并增强数据管理能力。 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏…

Ubuntu 22.04 LTS ffmpeg mp4 gif 添加图片水印

ffmpeg编译安装6.0.1&#xff0c;参考 Ubuntu 20.04 LTS ffmpeg gif mp4 互转 许编译安装ffmpeg &#xff1b;解决gif转mp4转换后无法播放问题-CSDN博客 准备一个logo MP4添加水印 ffmpeg -i 2.mp4 -vf "movielogo.png[watermark];[in][watermark]overlayx10:y10[out]&…