【Python】Jinja2:快速上手

2024-08-24 16:12
文章标签 python 快速 jinja2

本文主要是介绍【Python】Jinja2:快速上手,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Jinja2 是一个广泛使用的 Python 模板引擎,它允许你使用模板语法生成动态的 HTML、XML、或者其他文本文件。Jinja2 是 Flask 和 FastAPI 等 Web 框架中默认的模板引擎,但它也可以在任何 Python 项目中独立使用。

部署与使用

安装

pip install jinja2

导入模块和类

from jinja2 import Environment, FileSystemLoader
  • jinja2 是 Jinja2 模板引擎的 Python 模块。
  • Environment 是 Jinja2 的核心类之一,负责管理模板的全局配置、变量的全局设置,以及模板文件的加载方式。
    • Environment 的作用:这个类用于创建模板环境,管理模板的全局配置,如自动转义、缓存设置、扩展的使用等。在 Environment 对象中,可以定义如何加载模板、模板的编码格式、全局变量和过滤器等。
  • FileSystemLoader 是 Jinja2 中的一种加载器,用于从文件系统中的指定目录加载模板文件。
    • 加载器的作用:Jinja2 提供了多种加载器,FileSystemLoader 是其中最常用的一种,适用于从文件系统加载模板。加载器的作用是告诉 Jinja2 如何找到和读取模板文件。

创建模板环境

env = Environment(loader=FileSystemLoader('templates'))
  • env:这是一个 Environment 类的实例,代表 Jinja2 模板的全局环境。
    • Environment 的实例化:通过 Environment() 创建的 env 对象,负责管理和存储所有模板相关的配置和信息。
  • loader=FileSystemLoader('templates')
    • loader 参数Environment 类的一个关键参数,用于指定模板文件的加载器。在这里,我们使用 FileSystemLoader 加载器。
    • FileSystemLoader('templates'):指定了模板文件所在的目录 'templates',表示所有的模板文件都存放在这个文件夹中。
      • 作用:当你在后续代码中请求模板时,Jinja2 会在 templates 目录中查找相应的模板文件。

代码扩展:

可以在 Environment 中传递更多的配置参数,例如:

env = Environment(loader=FileSystemLoader('templates'),autoescape=True,  # 自动转义 HTML 特殊字符,防止 XSS 攻击cache_size=50,    # 设置缓存大小,提高模板加载的效率trim_blocks=True,  # 去除块级标签中的空白行lstrip_blocks=True  # 去除块级标签前的空白字符
)

加载模板

template = env.get_template('my_template.html')
  • template:这是一个 Template 对象,表示加载的模板文件。
    • 作用template 对象持有了 my_template.html 模板的内容,可以使用这个对象进行渲染操作。
  • env.get_template('my_template.html')
    • get_template 方法:这是 Environment 类的一个方法,用于加载指定的模板文件。
    • 参数 'my_template.html':指定了要加载的模板文件的名称。
      • 路径查找:Jinja2 会在 FileSystemLoader 指定的目录(即 'templates' 文件夹)中查找名为 my_template.html 的文件,并将其作为模板进行加载。
      • 返回值get_template() 方法返回一个 Template 对象,代表该模板文件,可以使用它进行渲染。

代码扩展:

  • 处理不存在的模板文件
    • 如果模板文件不存在,get_template 会抛出 TemplateNotFound 异常。你可以通过 try...except 结构来处理这个错误。
      try:template = env.get_template('non_existent_template.html')
      except TemplateNotFound:print("Template file not found!")
      

渲染模板

rendered_html = template.render(user_name="Alice", user_is_admin=True)
  • rendered_html:这是一个字符串变量,存储了渲染后的 HTML 或其他格式的内容。

    • 作用rendered_html 是模板渲染的最终结果,即在模板中填充变量后的完整内容,通常是 HTML 代码,但也可以是任何字符串形式的内容(例如纯文本、JSON 等)。
  • template.render()

    • render 方法:这是 Template 类的一个方法,用于将模板中的占位符替换为实际的值,从而生成最终的输出。
    • 作用render 方法会解析模板中的变量和控制结构,将传递的实际值插入到模板中,生成渲染后的内容。
  • 参数传递

    • user_name="Alice":向模板传递一个名为 user_name 的变量,值为 "Alice"
      • 作用:模板中所有引用 user_name 变量的地方都会被替换为 "Alice"
    • user_is_admin=True:向模板传递一个名为 user_is_admin 的布尔变量,值为 True
      • 作用:模板中所有引用 user_is_admin 变量的地方都会被替换为 True,并且可以用于控制结构(如条件语句)来决定是否显示特定内容。

代码扩展:

假设我们有以下模板 my_template.html

<!DOCTYPE html>
<html>
<head><title>User Info</title>
</head>
<body><h1>Welcome, {{ user_name }}!</h1>{% if user_is_admin %}<p>You have admin privileges.</p>{% else %}<p>You are a regular user.</p>{% endif %}
</body>
</html>

当我们使用 template.render(user_name="Alice", user_is_admin=True) 渲染这个模板时,最终生成的 rendered_html 将是:

<!DOCTYPE html>
<html>
<head><title>User Info</title>
</head>
<body><h1>Welcome, Alice!</h1><p>You have admin privileges.</p>
</body>
</html>

使用多变量渲染

除了单一变量传递外,render 方法可以接受任意数量的键值对参数:

rendered_html = template.render(user_name="Bob",user_is_admin=False,greeting="Hello",notifications=5
)

对应的模板可能会这样写:

<h1>{{ greeting }}, {{ user_name }}!</h1>
{% if notifications > 0 %}
<p>You have {{ notifications }} new notifications.</p>
{% else %}
<p>No new notifications.</p>
{% endif %}

渲染结果会是:

<h1>Hello, Bob!</h1>
<p>You have 5 new notifications.</p>

模板

变量插值

Jinja2 允许在模板中使用双花括号 {{ }} 语法插入变量。变量插值是 Jinja2 最基本的功能之一,通常用于动态生成内容。

示例代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Welcome Page</title>
</head>
<body><h1>Hello, {{ user_name }}!</h1><p>Welcome to our website. Your email is: {{ user_email }}</p>
</body>
</html>
Python 代码:
from jinja2 import Environment, FileSystemLoader# 创建 Jinja2 环境,指定模板文件的路径
env = Environment(loader=FileSystemLoader('templates'))# 加载模板文件
template = env.get_template('welcome.html')# 定义模板中需要插入的变量
context = {'user_name': 'Alice','user_email': 'alice@example.com'
}# 渲染模板并生成最终的 HTML
rendered_html = template.render(context)
print(rendered_html)
解释:
  • 变量插值{{ user_name }} 会在最终的 HTML 中被替换为 Alice{{ user_email }} 会被替换为 alice@example.com
  • 输出:最终生成的 HTML 将是:
    <h1>Hello, Alice!</h1>
    <p>Welcome to our website. Your email is: alice@example.com</p>
    

控制结构

Jinja2 支持常见的控制结构,如条件语句 (if)、循环 (for),这使得模板能够根据条件或数据动态生成不同的内容。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>User Dashboard</title>
</head>
<body><h1>Dashboard</h1>{% if user_is_admin %}<p>Welcome, admin! You have full access to the system.</p>{% else %}<p>Welcome, user! Your access is limited.</p>{% endif %}
</body>
</html>
context = {'user_is_admin': True
}rendered_html = template.render(context)
print(rendered_html)
循环语句示例代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Product List</title>
</head>
<body><h1>Available Products</h1><ul>{% for product in products %}<li>{{ product.name }} - ${{ product.price }}</li>{% else %}<li>No products available</li>{% endfor %}</ul>
</body>
</html>
Python 代码:
context = {'products': [{'name': 'Laptop', 'price': 1200},{'name': 'Smartphone', 'price': 800},{'name': 'Tablet', 'price': 450}]
}rendered_html = template.render(context)
print(rendered_html)
解释:
  • 条件语句{% if user_is_admin %} 判断用户是否为管理员,输出相应的欢迎信息。
  • 循环{% for product in products %} 遍历 products 列表,生成每个产品的列表项。如果 products 列表为空,{% else %} 分支会显示 “No products available”。
  • 输出
    <ul><li>Laptop - $1200</li><li>Smartphone - $800</li><li>Tablet - $450</li>
    </ul>
    

过滤器

Jinja2 提供了一系列内置过滤器,用于在模板中对变量进行格式化和处理。过滤器使用管道符号 | 进行应用,类似于 Unix 的管道操作。

常见过滤器示例:
  • upper:将字符串转换为大写。
  • lower:将字符串转换为小写。
  • date:格式化日期。
  • length:获取列表或字符串的长度。
示例代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>User Profile</title>
</head>
<body><h1>User Profile</h1><p>Name: {{ user_name | upper }}</p><p>Member since: {{ join_date | date("Y-m-d") }}</p><p>You have {{ notifications | length }} new notifications.</p>
</body>
</html>
Python 代码:
from datetime import datetimecontext = {'user_name': 'Alice','join_date': datetime(2021, 3, 15),'notifications': ['Message 1', 'Message 2', 'Message 3']
}rendered_html = template.render(context)
print(rendered_html)
解释:
  • upper 过滤器:将 user_name 转换为大写,即 Alice 变为 ALICE
  • date 过滤器:将 join_date 格式化为 YYYY-MM-DD 格式,如 2021-03-15
  • length 过滤器:计算 notifications 列表的长度,即显示 “You have 3 new notifications”。

模板继承

模板继承是 Jinja2 的一大特色,它允许你定义一个基础模板,并在其他模板中继承和扩展该基础模板。这有助于保持代码的可维护性和一致性,尤其是在处理大型项目时。

基础模板示例代码 (base.html):
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>{% block title %}My Website{% endblock %}</title>
</head>
<body><header><h1>My Website</h1><nav><a href="/">Home</a><a href="/about">About</a><a href="/contact">Contact</a></nav></header><main>{% block content %}{% endblock %}</main><footer><p>&copy; 2024 My Website</p></footer>
</body>
</html>
子模板示例代码 (home.html):
{% extends "base.html" %}{% block title %}Home - My Website{% endblock %}{% block content %}<h2>Welcome to the Home Page</h2><p>This is the main content of the home page.</p>
{% endblock %}
Python 代码:
template = env.get_template('home.html')
rendered_html = template.render()
print(rendered_html)
解释:
  • {% extends "base.html" %}home.html 继承了 base.html 中定义的结构和样式。
  • {% block title %}{% block content %}:子模板通过 block 标签重写了 base.html 中的特定部分,如标题和主要内容。
  • 输出
    <title>Home - My Website</title>
    <h2>Welcome to the Home Page</h2>
    <p>This is the main content of the home page.</p>
    

宏(Macros)

宏类似于 Python 中的函数,用于封装可重用的模板代码。使用宏可以避免重复代码,并简化复杂的模板逻辑。

宏定义与使用示例代码:
{% macro render_input(name, value='', type='text', placeholder='') %}<input type="{{ type }}" name="{{ name }}" value="{{ value }}" placeholder="{{ placeholder }}">
{% endmacro %}<form>{{ render_input('username', type='text', placeholder='Enter your username') }}{{ render_input('password', type='password', placeholder='Enter your password') }}<button type="submit">Login</button>
</form>
Python 代码:
template = env.get_template('form.html')
rendered_html = template.render()
print(rendered_html)
解释:
  • {% macro render_input %}:定义了一个名为 render_input 的宏,用于生成 <input> 表单元素。这个宏接收多个参数,如 namevaluetypeplaceholder
  • 宏的使用:通过调用 {{ render_input(...) }},可以生成自定义的输入框,而不需要重复编写 HTML 代码。
  • 输出
    <input type="text" name="username" value="" placeholder="Enter your username"><input type="password" name="password" value="" placeholder="Enter your password"><button type="submit">Login</button>

*FastAPI动态页面

在 FastAPI 中使用 Jinja2 渲染和返回动态页面是一种常见的做法,尤其是在需要生成动态 HTML 内容时。以下是详细步骤和代码示例,展示如何在 FastAPI 中集成 Jinja2 并返回动态页面。

安装依赖

首先,确保安装了 FastAPI 和 Jinja2 相关的依赖包:

pip install fastapi jinja2 uvicorn

项目结构

假设你的项目结构如下:

.
├── app.py
├── templates
│   └── index.html
  • app.py: 主应用程序文件。
  • templates: 存放 Jinja2 模板文件的目录。
  • index.html: 一个示例模板文件。

创建 FastAPI 应用并配置 Jinja2

app.py 中设置 FastAPI 应用程序并配置 Jinja2 进行模板渲染:

from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponseapp = FastAPI()# 配置 Jinja2 模板引擎
templates = Jinja2Templates(directory="templates")@app.get("/", response_class=HTMLResponse)
async def read_root(request: Request):# 渲染 index.html 模板,并传递上下文变量return templates.TemplateResponse("index.html", {"request": request, "user_name": "Alice", "user_is_admin": True})
  • Jinja2Templates(directory="templates"): 这行代码配置了 Jinja2 模板引擎,指定模板文件存放在 templates 目录下。
  • @app.get("/", response_class=HTMLResponse): 这个装饰器用于定义一个 GET 路由,当用户访问 / 时,这个函数会被调用。
  • TemplateResponse("index.html", {"request": request, "user_name": "Alice", "user_is_admin": True}):
    • TemplateResponse: 渲染 Jinja2 模板并返回一个 HTML 响应。
    • "index.html": 指定要渲染的模板文件。
    • {"request": request, "user_name": "Alice", "user_is_admin": True}: 传递给模板的上下文数据,request 对象是必须的,它用于模板内部访问 URL 路径等信息,其他变量如 user_nameuser_is_admin 可以在模板中使用。

创建模板文件

templates 目录下创建 index.html 文件:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Welcome</title>
</head>
<body><h1>Welcome, {{ user_name }}!</h1>{% if user_is_admin %}<p>You have admin privileges.</p>{% else %}<p>You are a regular user.</p>{% endif %}
</body>
</html>
  • {{ user_name }}: 用于插入 user_name 变量的值。
  • {% if user_is_admin %}: 控制结构,用于根据 user_is_admin 的值显示不同的内容。

启动 FastAPI 应用

在终端中启动 Uvicorn 服务器以运行 FastAPI 应用:

uvicorn app:app --reload

然后访问 http://127.0.0.1:8000/,你将看到渲染后的 HTML 页面。

这篇关于【Python】Jinja2:快速上手的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1102964

相关文章

Python 字典 (Dictionary)使用详解

《Python字典(Dictionary)使用详解》字典是python中最重要,最常用的数据结构之一,它提供了高效的键值对存储和查找能力,:本文主要介绍Python字典(Dictionary)... 目录字典1.基本特性2.创建字典3.访问元素4.修改字典5.删除元素6.字典遍历7.字典的高级特性默认字典

Python自动化批量重命名与整理文件系统

《Python自动化批量重命名与整理文件系统》这篇文章主要为大家详细介绍了如何使用Python实现一个强大的文件批量重命名与整理工具,帮助开发者自动化这一繁琐过程,有需要的小伙伴可以了解下... 目录简介环境准备项目功能概述代码详细解析1. 导入必要的库2. 配置参数设置3. 创建日志系统4. 安全文件名处

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

python生成随机唯一id的几种实现方法

《python生成随机唯一id的几种实现方法》在Python中生成随机唯一ID有多种方法,根据不同的需求场景可以选择最适合的方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习... 目录方法 1:使用 UUID 模块(推荐)方法 2:使用 Secrets 模块(安全敏感场景)方法

使用Python删除Excel中的行列和单元格示例详解

《使用Python删除Excel中的行列和单元格示例详解》在处理Excel数据时,删除不需要的行、列或单元格是一项常见且必要的操作,本文将使用Python脚本实现对Excel表格的高效自动化处理,感兴... 目录开发环境准备使用 python 删除 Excphpel 表格中的行删除特定行删除空白行删除含指定

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

Python办公自动化实战之打造智能邮件发送工具

《Python办公自动化实战之打造智能邮件发送工具》在数字化办公场景中,邮件自动化是提升工作效率的关键技能,本文将演示如何使用Python的smtplib和email库构建一个支持图文混排,多附件,多... 目录前言一、基础配置:搭建邮件发送框架1.1 邮箱服务准备1.2 核心库导入1.3 基础发送函数二、

Python包管理工具pip的升级指南

《Python包管理工具pip的升级指南》本文全面探讨Python包管理工具pip的升级策略,从基础升级方法到高级技巧,涵盖不同操作系统环境下的最佳实践,我们将深入分析pip的工作原理,介绍多种升级方... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Python中反转字符串的常见方法小结

《Python中反转字符串的常见方法小结》在Python中,字符串对象没有内置的反转方法,然而,在实际开发中,我们经常会遇到需要反转字符串的场景,比如处理回文字符串、文本加密等,因此,掌握如何在Pyt... 目录python中反转字符串的方法技术背景实现步骤1. 使用切片2. 使用 reversed() 函