Jinja 模板引擎实战指南(Python)

Jinja2 是 Python 模板引擎:变量、控制结构、模板继承、宏与过滤器。本文结合 Flask 应用实战,讲清 Jinja 的核心概念与进阶用法。

最佳实践
并发任务的多路径协同插画

直接回答:Jinja2 是 Python 生态的事实标准模板引擎——Flask、Ansible、SaltStack、Sphinx 都在用。语法简洁但功能完备:继承、宏、过滤器、测试器一应俱全,平衡了简单与强大。

Jinja 的生态位

出自 Flask 作者 Armin Ronacher 之手,灵感来自 Django 模板但表达力更强。如今它的身影遍布:Web 框架(Flask)、配置管理(Ansible playbook)、静态站点生成、文档系统、邮件与报表模板。学会一处,处处受用。

安装与最小用法

pip install jinja2
from jinja2 import Environment, FileSystemLoader, select_autoescape

env = Environment(loader=FileSystemLoader("templates"),
                  autoescape=select_autoescape(["html", "htm", "xml"]))
tpl = env.get_template("hello.html")
print(tpl.render(name="世界"))

Flask 中无需配置——render_template("page.html", ...) 直接可用。

核心语法

<h1>{{ title }}</h1>                      <!-- 变量插值(自动转义) -->

{% if user.is_admin %}
  <a href="/admin">管理后台</a>
{% endif %}

<ul>
{% for item in items %}
  <li>{{ loop.index }}. {{ item.name }}</li>   <!-- loop 内置计数 -->
{% else %}
  <li>暂无数据</li>
{% endfor %}
</ul>

模板继承:布局复用的基石

<!-- base.html -->
<html>
<body>
  {% block content %}{% endblock %}
</body>
</html>

<!-- page.html -->
{% extends "base.html" %}
{% block content %}
  <h2>{{ post.title }}</h2>
  <article>{{ post.body }}</article>
{% endblock %}

extends + block 让全站布局只写一遍,子模板只填差异部分。

宏:可复用的模板组件

{% macro render_post(post) %}
<div class="card">
  <h3>{{ post.title }}</h3>
  <p>{{ post.summary }}</p>
</div>
{% endmacro %}

{{ render_post(p) }}

宏之于模板相当于函数之于代码——列表页、详情页复用同一渲染逻辑。

过滤器与测试器

{{ post.title|upper }}                    <!-- 大写 -->
{{ price|round(2) }}                      <!-- 保留两位 -->
{{ items|length }}                        <!-- 长度 -->
{{ created|datetimeformat("%Y-%m-%d") }}  <!-- 自定义过滤器 -->
{{ body|safe }}                           <!-- 关闭转义(慎用) -->
{{ user.email|default("未填写") }}         <!-- 默认值 -->

常用测试:{% if x is defined %}、{% if n is divisibleby(3) %}。内置过滤器覆盖常用转换,剩下的注册自定义过滤器(一个 Python 函数 + env.filters)。

安全须知

  • 独立 Jinja Environment 不默认开启自动转义,本文显式配置 select_autoescape;Flask 会对常见 HTML 模板启用——跨站脚本(XSS)防线,别随意用 |safe 关闭;
  • 渲染用户提供的模板代码是危险操作,不应直接信任用户模板。SandboxedEnvironment 只能限制部分操作,仍需最小可见对象、CPU/内存限额、隔离及及时安全更新。

常见问题(FAQ)

Q:Jinja 和 Django 模板怎么选?
A:用 Django 就跟随内置模板(与 Admin/表单联动深);其他场景 Jinja 表达力更强、生态更广。两者语法相似,迁移成本低。

Q:模板里能写复杂逻辑吗?
A:能写不代表该写。模板负责展示,业务逻辑留在视图/服务层。发现自己在模板里写大段 if-else 时,把计算挪回 Python。

Q:Ansible 里的 Jinja 有什么不一样?
A:语法相同但上下文是 Ansible 变量与 facts,且有一堆 Ansible 专属过滤器(to_json、b64encode 等)。踩坑点:YAML 与 Jinja 的花括号冲突需要引号包裹。

官方参考

本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台