Jinja2 是一个现代的,功能强大的 Python 模板引擎。它是 Flask 和 Django 等流行 Web 框架的默认模板引擎,同时也可以作为独立的模板引擎使用。以下是 Jinja2 的全部教程,包括基础语法、控制结构、过滤器、宏和继承等内容。
## 1. 基础语法
### 1.1 变量
在 Jinja2 中,可以使用`{{ ... }}`语法来输出变量的值。例如:
~~~
{% set name = "Alice" %}
<p>我的名字是 {{ name }}。</p>
~~~
在上面的代码中,使用`{% set name = "Alice" %}`定义了一个名为`name`的变量,并在`<p>`标签中使用`{{ name }}`输出了该变量的值。
### 1.2 注释
在 Jinja2 中,可以使用`{# ... #}`语法来添加注释。例如:
~~~
{# 这是一个注释 #}
<p>这是一个段落。</p>
~~~
在上面的代码中,使用`{# ... #}`添加了一个注释,不会在 HTML 中显示。
### 1.3 控制结构
在 Jinja2 中,可以使用`{% ... %}`语法来添加各种控制结构,例如条件语句、循环语句等。例如:
~~~
{% if name == "Alice" %}
<p>你好,{{ name }}!</p>
{% elif name == "Bob" %}
<p>你好,{{ name }}!</p>
{% else %}
<p>你好,陌生人!</p>
{% endif %}
~~~
在上面的代码中,使用`{% if ... %}`、`{% elif ... %}`、`{% else %}`和`{% endif %}`构建了一个条件语句,根据变量`name`的值输出不同的内容。
### 1.4 过滤器
在 Jinja2 中,可以使用`|`语法来应用各种过滤器,例如格式化日期、字符串转换等。例如:
~~~
<p>今天是 {{ now()|date('Y年m月d日') }}。</p>
~~~
在上面的代码中,使用`now()`函数获取当前日期时间,然后使用`|date('Y年m月d日')`过滤器将日期格式化为`Y年m月d日`的形式。
### 1.5 常量
在 Jinja2 中,可以使用常量来表示一些不变的值,例如`true`、`false`、`none`等。例如:
~~~
{% set x = none %}
{% if x is none %}
<p>x 是空值。</p>
{% endif %}
~~~
在上面的代码中,使用`none`常量表示一个空值,然后使用`is none`条件判断语句判断变量`x`是否为空值。
## 2. 控制结构
### 2.1 条件语句
在 Jinja2 中,可以使用`{% if ... %}`、`{% elif ... %}`、`{% else %}`和`{% endif %}`构建条件语句。例如:
~~~
{% if x > 0 %}
<p>x 是正数。</p>
{% elif x < 0 %}
<p>x 是负数。</p>
{% else %}
<p>x 是零。</p>
{% endif %}
~~~
在上面的代码中,根据变量`x`的值输出不同的内容。
### 2.2 循环语句
在 Jinja2 中,可以使用`{% for ... in ... %}`和`{% endfor %}`构建循环语句。例如:
~~~
{% for item in items %}
<p>{{ item }}</p>
{% endfor %}
~~~
在上面的代码中,使用`{% for ... in ... %}`循环遍历列表`items`中的元素,并使用`{{ item }}`输出每个元素的值。
### 2.3 宏
在 Jinja2 中,可以使用`{% macro ... %}`和`{% endmacro %}`定义宏,以便在模板中重复使用一些代码块。例如:
~~~
{% macro hello(name) %}
<p>你好,{{ name }}!</p>
{% endmacro %}
{{ hello("Alice") }}
{{ hello("Bob") }}
~~~
在上面的代码中,使用`{% macro ... %}`定义了一个名为`hello`的宏,然后在模板中多次调用该宏,并传递不同的参数。
## 3. 过滤器
### 3.1 基本过滤器
在 Jinja2 中,可以使用各种过滤器来转换、格式化和操作变量的值。例如:
~~~
{{ name|upper }}
{{ age|round }}
{{ text|truncate(50) }}
~~~
在上面的代码中,使用`|`语法应用了三个过滤器,分别将变量`name`转换为大写字母、将变量`age`四舍五入、将变量`text`截取为最多 50 个字符。
### 3.2 自定义过滤器
在 Jinja2 中,可以使用`Environment.filters`属性或`@app.template_filter`装饰器来定义自定义过滤器。例如:
~~~
from jinja2 import Environment
def reverse_filter(value):
return value[::-1]
env = Environment()
env.filters["reverse"] = reverse_filter
# 或者使用 @app.template_filter
@app.template_filter("reverse")
def reverse_filter(value):
return value[::-1]
~~~
在上面的代码中,定义了一个名为`reverse_filter`的自定义过滤器,并将其添加到 Jinja2 环境中。然后,在模板中就可以使用`|reverse`过滤器来调用该自定义过滤器。
## 4. 继承和包含
### 4.1 继承
在 Jinja2 中,可以使用`{% extends ... %}`和`{% block ... %}`构建模板继承关系,以便在不同的模板中重用相同的代码块。例如:
~~~
<!-- base.html -->
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
~~~
~~~
<!-- child.html -->
{% extends "base.html" %}
{% block title %}
我是子模板的标题
{% endblock %}
{% block content %}
<p>这是子模板的内容。</p>
{% endblock %}
~~~
在上面的代码中,定义了一个名为`base.html`的父模板和一个名为`child.html`的子模板,并使用`{% extends ... %}`和`{% block ... %}`构建了模板继承关系。子模板继承了父模板的结构和内容,并在其中重定义了两个模板块。
### 4.2 包含
在 Jinja2 中,可以使用`{% include ... %}`包含其他的模板文件,以便在模板中重用相同的代码块。例如:
~~~
<!-- header.html -->
<header>
<h1>这是一个标题</h1>
</header>
~~~
~~~
<!-- footer.html -->
<footer>
<p>版权所有 © 2022</p>
</footer>
~~~
~~~
<!-- page.html -->
<!DOCTYPE html>
<html>
<head>
<title>页面标题</title>
</head>
<body>
{% include "header.html" %}
<p>这是页面的内容。</p>
{% include "footer.html" %}
</body>
</html>
~~~
在上面的代码中,定义了三个模板文件,分别表示页面的头部、尾部和内容。然后,在`page.html`模板中使用`{% include ... %}`包含了头部和尾部的模板文件,以便在页面中重用这些代码块。
以上就是 Jinja2 的全部教程,涵盖了 Jinja2 的基础语法、控制结构、过滤器、宏、继承和包含等多个方面,希望对您有所帮助。下面是一些常见问题和答案,供参考。
### Q: Jinja2 和 Django 模板引擎有什么区别?
Jinja2 和 Django 模板引擎都是 Python 的模板引擎,用于生成 HTML、XML 等文本格式的输出。它们的语法和功能有一些区别,主要体现在以下几个方面:
* 语法:Jinja2 的语法更加简洁和灵活,支持更多的控制结构和过滤器。而 Django 模板引擎的语法相对较为简单,支持的控制结构和过滤器较少。
* 性能:Jinja2 的性能比 Django 模板引擎更快,尤其在处理大量数据和复杂逻辑时表现更加出色。
* 集成性:Jinja2 可以方便地与 Flask、Tornado、Google App Engine 等多个 Python 框架集成,而 Django 模板引擎则是 Django 框架的默认模板引擎,与 Django 框架集成更为紧密。
### Q: Jinja2 如何处理模板中的 HTML 转义问题?
Jinja2 默认会自动将模板中的 HTML 特殊字符进行转义,以避免 XSS 攻击等安全问题。例如,将`<`转义为`<`,将`>`转义为`>`,将`&`转义为`&`等。如果希望输出原始的 HTML 内容,可以使用`safe`过滤器。例如:
~~~
{{ html|safe }}
~~~
在上面的代码中,使用`safe`过滤器告诉 Jinja2 输出原始的 HTML 内容,而不进行转义。
需要注意的是,使用`safe`过滤器可能存在安全风险,应该谨慎使用,并确保输出的内容是可信的。
### Q: Jinja2 如何处理模板中的变量作用域问题?
Jinja2 中的变量作用域遵循类似 Python 的作用域规则,即内部作用域可以访问外部作用域的变量,但外部作用域不能访问内部作用域的变量。例如:
~~~
{% set x = 1 %}
{% if true %}
{% set y = 2 %}
{% endif %}
<p>x = {{ x }}, y = {{ y }}</p>
~~~
在上面的代码中,变量`x`定义在外部作用域中,可以被内部作用域访问。变量`y`定义在内部作用域中,只能在条件语句中访问,外部作用域无法访问。
需要注意的是,如果在模板中使用了`{% include ... %}`或`{% extends ... %}`等构建模板继承关系的语句,则变量作用域会被继承和覆盖,需要特别注意。
### Q: Jinja2 如何处理模板中的循环引用问题?
Jinja2 中的循环引用问题指的是,当模板 A 包含了模板 B,并且模板 B 也包含了模板 A 时,会产生无限循环的引用关系,导致程序崩溃。为了避免这种情况,Jinja2 提供了`{% include ... ignore missing %}`语法,表示如果模板文件不存在,则忽略该错误,并继续执行后续的代码。例如:
~~~
{% include "header.html" ignore missing %}
~~~
在上面的代码中,如果模板文件`header.html`不存在,则忽略该错误,并继续执行后续的代码。
需要注意的是,使用`{% include ... ignore missing %}`可能会导致模板中的某些部分缺失或功能不完整,应该谨慎使用。最好的解决方案是避免循环引用问题的产生,优化模板结构和组织方式。
.
一些 Jinja2 的教程和资源,您可以参考学习:
Jinja2 官方文档:https://docs.jinkan.org/docs/jinja2/
除了以上教程,还有一些 Jinja2 的插件和扩展,可以为您的开发工作带来更多便利和功能,例如:
* [jinja2-time](https://github.com/hustcc/jinja2-time):Jinja2 的日期和时间处理插件。
* [jinja2-cli](https://github.com/mattrobenolt/jinja2-cli):Jinja2 命令行工具,可以方便地渲染模板文件。
* [Flask-Jinja2](https://github.com/pallets/flask/tree/main/src/flask/templating.py):Flask 框架默认使用的 Jinja2 扩展,提供了更多的功能和集成方式。
希望这些资源可以帮助您更好地学习和使用 Jinja2。
- 开发环境
- 安装开发环境
- pip下载换源
- python 下载加速
- 安装多个版本的python
- 使用pypy解释器
- 使用pyston解释器
- 生成和安装requirements.txt依赖
- python 3.10.11
- 环境
- 资源
- python安装模块的几种方法
- 常用操作类
- py310_db_20231021
- 使用nuitka打包
- nuitka常用指令
- 请求封装
- 代理ip测试
- 使用pyjion加速
- 20240608环境
- 大牛资源复制
- 编译成so文件
- python基础
- 变量与基本数据类型
- 变量
- 基本数据类型
- 运算符
- 流程控制
- if 语句
- while 循环
- for循环
- break,continue,pass
- with...as 语句
- 列表与元组
- 列表的创建和访问
- 列表的运算
- 列表元素的操作
- 元组的创建和访问
- 列表和元组 推导式
- 字典与集合
- 字典的创建和访问
- 字典元素的操作
- 字典推导式
- 集合的创建,元素的操作
- 集合的运算
- 字典排序
- 字符串与编码
- 字符串编码
- 字符串操作
- 字符串格式化
- 面向对象编程
- 函数
- 类
- 类里面的常用的方法
- 反射
- 异常处理和调试
- 异常
- 异常处理
- 文件/IO 操作
- 创建和关闭文件
- 写入和读取
- IO操作图片
- HTTP网络编程
- requests请求封装模块(一)
- requests请求封装模块(二)
- requests请求封装模块(三)
- http请求表单 multipart/form-data
- httpbin
- http
- http请求模块
- 使用代理IP
- http 请求 单独cookie
- http请求模块 session cookies
- 数据库
- 安装mysql数据库
- 操作mysql数据库
- MySql数据库链接池操作类
- SQLite数据库操作
- SQLite查询元组转字典
- SQLite数据库操作类
- SQLite数据库操作类2
- SQLite数据库链接池操作类
- aiosqlite 异步数据库操作类
- sqlite 数据库操作类
- 使用DuckDB数据库
- DuckDB数据库操作类
- DuckDB插入重复数据替换
- apsw sqlite操作类
- peewee sqlite数据库操作类
- sqlite3 数据库操作类
- 字典模式 sqlite3 操作类
- 字典模式 peewee 操作类
- Berkeley DB数据库操作
- Firebird 数据库操作
- sqlite3 运算符
- sqlite的数据类型
- sqlite 语句分页
- sqlite数据库去重复
- 多协程
- 协程 Coroutine
- 生成器 yield
- 异步IO框架-asyncio
- 异步IO框架-asyncio(二)
- 异步IO框架-asyncio(三)
- 协程 greenlet
- 协程 gevent
- 协程池 gevent.Pool
- 多线程
- 使用多线程
- 多线程中常用的方法
- 线程同步(锁)和通信
- 线程同步(锁)和通信(二)
- 使用队列的线程通信
- 使用队列管理线程-线程池
- 线程池-threadpool
- 线程池-ThreadPoolExecutor
- 线程池-ThreadPoolExecutor(二)
- 线程池-ThreadPoolExecutor(三)
- 多线程获取
- 线程池kun
- multiprocessing 线程池
- 多进程
- 使用多进程
- 多进程中常用的方法
- 进程同步(锁)和通信
- 进程同步(锁)和通信(二)
- 进程池-multiprocessing.Pool
- 进程池-ProcessPoolExecutor
- Flask web开发
- 安装调试 flask 模块
- Flask的Http方法
- 宝塔部署 flask 项目
- 错误处理机制
- fastapi 开发
- 入门
- 路径和参数
- 请求体
- html模板渲染
- 静态文件设置
- html发起GET请求
- html发起POST请求
- 重写异常
- 设置公共部分
- Jinja2 教程
- 使用hypercorn服务器
- 使用uvicorn服务器
- 使用vue.js 渲染html
- fastapi 设置响应超时
- post请求接收表单数据
- fastapi 上传文件
- asyncio 防止堵塞
- 设置cookie鉴权
- swagger
- request 对象
- response 对象
- 提前创建 和 退出前关闭
- fastapi接口压力测试
- 中间件使用技巧
- 使用ssl证书变成https
- 加密解密
- Base64
- AES
- RSA
- DES
- 加密算法
- MD5 哈希算法加密
- RSA公钥解密[解密对应私钥的加密]
- HMAC-SHA1
- OCR图像识别
- muggle_ocr
- ddddocr
- easyocr
- cv2裁剪图片
- 处理url中常见的图片
- 使用cv2 匹配滑块缺口
- 安卓逆向
- adb 手机调试
- frida
- frida-server
- objection
- objection注入报错 双进程保护
- frida-dexdump 安卓app脱壳
- Android-apktool 脱壳
- frida注入hook脚本脱壳
- Jadx 反编译
- 在安卓模拟器上使用frida
- SimpleHook
- 应用伪装
- python frida
- 使用 hook 脚本
- 编写hook 脚本
- 枚举当前加载的模块及模块中方法
- 万能的hook Md5 脚本
- hook常用js函数封装
- frida工具-FridaInfoShow
- frida工具-fridaUiTools
- frida工具-appmon
- frida工具-ZenTracer-master
- frida工具-Dwarf
- frida工具-lamda
- frida抓包工具 r0capture
- 脱壳工具
- python调用浏览器
- 常用方法
- for while 循环显示进度
- 打印艺术字或者图案
- json.dumps()中文乱码
- 队列构造循环池
- 模糊匹配 in 关键词用法
- python中的编码声明
- 列表平均分割
- requests 不使用代理 防止抓包
- 递增矩阵算法
- 判断是否是中文
- 数组内的字典关键词排序
- 垃圾回收释放内存
- 打印异常程序不停止
- 判断json数据
- 判断url是否合法
- 字符串空格步长统一和数组转字符串
- 监控内存使用情况
- 监控cpu使用情况
- 获取机器码
- 取16个随机字符串加密
- parsel解析html
- 三元表达式
- py调用js函数
- js加密算法-护世界app
- 中国大学AES例子
- 字典转字符串
- 提取requests里面cookie
- MD5算法js还原
- 优学院app一个md5算法
- 字符串转字节和字节数组
- 池馆一个js-AES-CRT算法
- 屏蔽抓包工具
- request重定向
- 常用获取时间接口
- bs4解析html
- 递归例子
- bs4 查找匹配
- 使用socks5代理
- 检测代理ip
- json解析优化
- python代码可视化
- 读写文件操作技巧
- requests模块优化
- 模块优化
- bs4截取js里面字符串
- requests传递多个同名参数
- 压力测试
- gevent模块报错
- nuitka 查看所有插件
- nuitka
- nuitka打包指定插件位置
- 修改python中sqlite3版本
- 使用pyinstaller打包
- pyinstaller打包 exe 反编译逆向
- execjs执行js报错;UnicodeEncodeError: ‘gbk‘
- 截取html标签里面的字符串
- lxml解析网页
- lxml使用css选择器
- 常用排序
- 字典循环输出
- 模块包技巧
- 调用验证码接口
- bs4 技巧
- 查看对象大小
- 运行的时候不生成pyc
- requests慢 浏览器 postman正常
- 数组相同分配
- 常用的时间转换方法
- tcp网络调优
- 防止未知报错闪退
- bs4报错UnicodeEncodeError
- 多条件判断优化
- 判断字符串中是否包含中文
- 读取文件报错 UnicodeDecodeError: 'gbk' ...
- 常规数据正则匹配验证
- 题目字符串截取方案
- fastapi防止堵塞的方案分析
- 调试内存泄漏
- 判断字符串中英文
- 获取系统信息
- curl_cffi和request模块一样牛逼的模块
- js逆向
- 使用fiddler修改网页的js
- 浏览器hook算法