1. 什么是 Jinja2? #

2. 模板语法 #

2.1 三种定界符 #

写法 作用 示例
{# ... #} 注释,不输出 {# 这是注释 #}
{{ ... }} 输出变量或表达式 {{ user.name }}
{% ... %} 控制语句(if/for/extends 等) {% if ok %}...{% endif %}

2.2 变量与常用过滤器 #

过滤器 作用 示例
upper / lower 大小写转换 `{{ name\ upper }}`
default 值为空时用默认值 `{{ name\ default('匿名') }}`
length 取长度 `{{ users\ length }}`
join 列表拼成字符串 `{{ tags\ join(', ') }}`
e / escape HTML 转义 `{{ text\ e }}`
safe 标记为安全 HTML(慎用) `{{ html\ safe }}`

2.3 条件判断 #

{# 说明:若 score 大于等于 90,输出「优秀」 #}
{% if score >= 90 %}
    优秀
{# 说明:否则若 score 大于等于 60,输出「及格」 #}
{% elif score >= 60 %}
    及格
{# 说明:以上都不满足时输出「不及格」 #}
{% else %}
    不及格
{# 说明:结束 if 语句块 #}
{% endif %}

2.4 循环 #

loop 属性 含义
loop.index 当前序号(从 1 开始)
loop.first 是否第一个元素
loop.last 是否最后一个元素
loop.length 总元素数
{# 说明:开始无序列表 #}
<ul>
{# 说明:遍历 users 列表中的每个 user #}
{% for user in users %}
    {# 说明:输出序号和用户名 #}
    <li>{{ loop.index }}. {{ user.name }}</li>
{# 说明:若 users 为空,执行 else 分支 #}
{% else %}
    <li>暂无数据</li>
{# 说明:结束 for 循环 #}
{% endfor %}
</ul>

3. 基本使用 #

3.1 字符串模板(适合简单场景) #

# 说明:从 jinja2 导入 Template 类,用于从字符串创建模板
from jinja2 import Template

# 说明:用字符串创建模板,{{ name }} 是占位符
template = Template("你好,{{ name }}!")

# 说明:传入 name 变量并渲染模板
result = template.render(name="小明")

# 说明:打印渲染结果
print(result)

3.2 从文件加载(项目常用) #

# 说明:导入 Environment 环境类
# 说明:导入 FileSystemLoader,从文件夹加载模板
# 说明:导入 select_autoescape,按文件类型自动转义 HTML
from jinja2 import Environment, FileSystemLoader, select_autoescape

# 说明:创建模板环境,指定 templates 目录并开启 HTML 自动转义
env = Environment(
    loader=FileSystemLoader("templates"),
    autoescape=select_autoescape(["html", "xml"]),
)

# 说明:加载 user_list.html 模板文件
template = env.get_template("user_list.html")

# 说明:传入变量并渲染为 HTML 字符串
html = template.render(title="用户列表", users=["Alice", "Bob"])

# 说明:打印渲染结果
print(html)

templates/user_list.html:

{# 说明:HTML 文档类型声明 #}
<!DOCTYPE html>
{# 说明:html 根元素 #}
<html>
{# 说明:页面头部 #}
<head>
    {# 说明:输出 title 变量作为页面标题 #}
    <title>{{ title }}</title>
</head>
{# 说明:页面主体 #}
<body>
    {# 说明:输出一级标题 #}
    <h1>{{ title }}</h1>
    {# 说明:开始无序列表 #}
    <ul>
    {# 说明:遍历 users 列表 #}
    {% for user in users %}
        {# 说明:输出每个用户名 #}
        <li>{{ user }}</li>
    {# 说明:结束 for 循环 #}
    {% endfor %}
    </ul>
    {# 说明:输出用户总数 #}
    <p>共 {{ users|length }} 人</p>
</body>
</html>

4. 模板继承 #

templates/base.html(父模板):

{# 说明:HTML 文档声明 #}
<!DOCTYPE html>
{# 说明:html 根元素 #}
<html>
{# 说明:页面头部 #}
<head>
    {# 说明:title 块,子模板可覆盖,默认「我的网站」 #}
    <title>{% block title %}我的网站{% endblock %}</title>
</head>
{# 说明:页面主体 #}
<body>
    {# 说明:网站头部区域 #}
    <header><h1>网站头部</h1></header>
    {# 说明:主内容区域,子模板填充 content 块 #}
    <main>{% block content %}{% endblock %}</main>
    {# 说明:页脚版权信息 #}
    <footer>&copy; 2026 示例公司</footer>
</body>
</html>

templates/profile.html(子模板):

{# 说明:继承 base.html 父模板 #}
{% extends "base.html" %}

{# 说明:覆盖 title 块 #}
{% block title %}个人中心{% endblock %}

{# 说明:填充 content 块 #}
{% block content %}
    {# 说明:输出用户名 #}
    <h2>欢迎,{{ user.name }}</h2>
    {# 说明:个人信息说明文字 #}
    <p>这里是个人信息页。</p>
{# 说明:结束 content 块 #}
{% endblock %}

5. 引入子模板(include) #

templates/header.html:

{# 说明:导航栏 #}
<nav>
    {# 说明:首页链接 #}
    <a href="/">首页</a>
    {# 说明:关于页链接 #}
    <a href="/about">关于</a>
</nav>

templates/page.html:

{# 说明:引入 header.html 导航片段 #}
{% include 'header.html' %}
{# 说明:主内容区 #}
<main>
    {# 说明:页面标题 #}
    <h1>{{ title }}</h1>
    {# 说明:页面正文 #}
    <p>{{ content }}</p>
</main>

6. 安全与自动转义 #

{# 说明:自动转义开启时,user_input 中的 HTML 标签会被转义 #}
{{ user_input }}

{# 说明:仅用于已确认安全的 HTML,慎用 #}
{{ trusted_html|safe }}

{# 说明:手动强制 HTML 转义 #}
{{ user_input|e }}

7. 常见问题 #

7.1 模板找不到(TemplateNotFound) #

7.2 变量显示为空 #

7.3 UndefinedError 或未定义变量 #

8. API 速查 #

操作 写法
字符串模板 Template("{{ x }}").render(x=1)
加载文件模板 Environment(loader=FileSystemLoader("templates"))
开启 HTML 转义 autoescape=select_autoescape(["html", "xml"])
获取模板 env.get_template("a.html")
渲染 template.render(name="Tom", users=[])
输出变量 {{ name }}
条件 {% if %}...{% elif %}...{% else %}...{% endif %}
循环 {% for x in xs %}...{% endfor %}
定义块 {% block content %}{% endblock %}
继承 {% extends "base.html" %}
引入片段 {% include "header.html" %}
过滤器 `{{ val\ upper }}、{{ val\ default('') }}`
Flask 渲染 render_template("a.html", name="Tom")