跳到主要内容
Python Flask 框架与 Jinja2 模板引擎配置使用指南 | 极客日志
Python
Python Flask 框架与 Jinja2 模板引擎配置使用指南 Python Flask 框架默认集成 Jinja2 模板引擎,用于将数据渲染至 HTML 页面。涵盖环境搭建、目录结构配置、模板渲染基础语法、变量与控制结构、模板继承、静态文件引用及高级特性如宏、过滤器、全局变量注入等内容。通过示例代码展示如何自定义模板路径、处理表单数据、实现国际化支持及安全转义机制,帮助开发者高效构建动态 Web 应用。
Stephaine Walsh 发布于 2026/2/26 更新于 2026/6/2 33 浏览1. Flask 与 Jinja2 简介
Flask 是一个轻量级的 Python Web 框架,默认集成了模板引擎 Jinja2 。
Jinja2 用于将数据渲染到 HTML 页面,实现前后端分离。
2. 环境安装
确保已安装 Flask 开发环境。Flask 会自动安装 Jinja2。
3. 基本目录结构
推荐结构如下:
your_project/
├── app.py
├── templates/
│ └── index.html
└── static /
└── style.css
templates/ 存放 Jinja2 模板
static/ 存放静态文件(如 CSS、JS、图片)
4. Flask 配置模板目录
Flask 默认读取 templates/ 目录。如果你想自定义:
app = Flask(__name__, template_folder='your_templates_folder' )
5. 使用 Jinja2 模板
5.1. 创建模板文件
templates/index.html :
<!DOCTYPE html >
<html >
<head >
<title > {{ title }}</title >
</head >
<body >
<h1 > Hello, {{ name }}!</h1 >
<ul >
{% for item in items %}
<li > {{ item }}</li >
{% endfor %}
</ul >
</body >
</html >
5.2. 后端渲染模板
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/' )
def index ():
return render_template(
'index.html' ,
title='首页' ,
name='小明' ,
items=['苹果' , '香蕉' , '橘子' ]
)
if __name__ == '__main__' :
app.run(debug=True )
6. Jinja2 语法详解
变量 :{{ variable }}
控制结构 :{% if %} ... {% endif %},{% for %} ... {% endfor %}
注释 :{# 注释内容 #}
过滤器 :{{ name|upper }},{{ list|length }}
例子 {% if items %}
<ul >
{% for item in items %}
<li > {{ item|capitalize }}</li >
{% endfor %}
</ul >
{% else %}
<p > 没有内容。</p >
{% endif %}
7. 传递更多数据类型 user = {'name' : '小红' , 'age' : 18 }
return render_template('index.html' , user=user)
<p > 姓名:{{ user.name }}</p >
<p > 年龄:{{ user.age }}</p >
8. 模板继承
8.1. 基础模板 <!DOCTYPE html >
<html >
<head >
<title > {% block title %}我的网站{% endblock %}</title >
</head >
<body >
<div >
{% block content %}{% endblock %}
</div >
</body >
</html >
8.2. 子模板 {% extends "base.html" %}
{% block title %}首页{% endblock %}
{% block content %}
<h1 > 欢迎来到首页</h1 >
{% endblock %}
9. 静态文件引用 <link rel ="stylesheet" href ="{{ url_for('static', filename='style.css') }}" >
10. 配置 Jinja2 高级选项 你可以自定义 Jinja2 的配置,例如自定义分隔符:
app.jinja_env.variable_start_string = '[['
app.jinja_env.variable_end_string = ']]'
11. 常见问题
模板文件放错目录,导致找不到
变量名拼写错误
控制结构语法错误
12. Jinja2 过滤器和自定义过滤器
12.1 常用内置过滤器
{{ name|capitalize }} 首字母大写
{{ text|safe }} 标记为安全 HTML,不会被转义
{{ items|length }} 获取列表长度
{{ price|round(2) }} 保留两位小数
12.2 自定义过滤器 def reverse_string (s ):
return s[::-1 ]
app.jinja_env.filters['reverse' ] = reverse_string
<p > {{ name|reverse }}</p >
13. Jinja2 宏(Macro) {% macro render_input(name, type='text') %}
<input type ="{{ type }}" name ="{{ name }}" value ="{{ value }}" >
{% endmacro %}
{% import "macros.html" as macros %}
{{ macros.render_input('username') }}
14. Jinja2 包含(Include) <header >
<h1 > 网站头部</h1 >
</header >
{% include 'header.html' %}
15. Jinja2 循环控制
loop.index 当前循环索引(从 1 开始)
loop.index0 当前循环索引(从 0 开始)
loop.first 是否第一个元素
loop.last 是否最后一个元素
<ul >
{% for item in items %}
<li > {{ loop.index }}: {{ item }}</li >
{% endfor %}
</ul >
16. 模板全局变量和上下文处理器 @app.context_processor
def inject_user ():
return dict (site_name='我的网站' )
17. 模板错误处理 如果模板变量不存在,默认不会报错而是显示空白。你可以用 default 过滤器:
{{ user.name|default('匿名') }}
18. Jinja2 与 Flask 表单结合(简单例子) from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/form' , methods=['GET' , 'POST' ] )
def form ():
if request.method == 'POST' :
username = request.form.get('username' )
msg = f'你好,{username} !'
return render_template('form.html' , msg=msg)
if __name__ == '__main__' :
app.run(debug=True )
<form method ="post" >
<input type ="text" name ="username" >
<input type ="submit" value ="提交" >
</form >
<p > {{ msg }}</p >
19. 模板缓存与自动刷新 开发阶段建议开启 debug=True,模板修改会自动刷新。生产环境建议关闭自动刷新以提升性能。
20. Jinja2 安全:自动转义与 safe 过滤器 Jinja2 默认会自动转义变量,防止 XSS 攻击。如果你确定内容安全,可以使用 safe:
21. 多模板目录配置 from flask import Flask
from jinja2 import ChoiceLoader, FileSystemLoader
app = Flask(__name__)
app.jinja_loader = ChoiceLoader([
FileSystemLoader('templates' ),
FileSystemLoader('more_templates' )
])
22. 国际化(i18n)支持 Flask-Babel 可以帮助你实现模板的多语言支持:
23. Jinja2 调试技巧
使用 {% set var = value %} 在模板中定义变量
使用 {% debug %} 可以打印当前上下文(需要手动扩展)
24. 复杂项目推荐结构 your_project/
├── app.py
├── templates/
│ ├── base.html
│ ├── index.html
│ └── macros.html
├── static /
│ ├── css/
│ └── js/
├── blueprints/
│ └── user.py
└── config.py
25. Jinja2 条件判断的高级用法 {% if score >= 90 %}
<p > 优秀</p >
{% elif score >= 60 %}
<p > 及格</p >
{% else %}
<p > 不及格</p >
{% endif %}
{% if user and user.is_admin %}
<p > 管理员操作区</p >
{% endif %}
26. Jinja2 设置变量和作用域 {% set total = price * quantity %}
<p > 总价:{{ total }}</p >
变量作用域仅限于当前块或模板,不会影响到其他地方。
27. Jinja2 的'块'与模板继承的实战 <!DOCTYPE html >
<html >
<head >
<title > {% block title %}默认标题{% endblock %}</title >
</head >
<body >
<nav >
{% block nav %}默认导航{% endblock %}
</nav >
<main >
{% block content %}{% endblock %}
</main >
</body >
</html >
{% extends "base.html" %}
{% block title %}具体页面标题{% endblock %}
{% block nav %}
<a href ="/" > 首页</a > | <a href ="/user" > 用户中心</a >
{% endblock %}
{% block content %}
<h1 > 页面内容</h1 >
{% endblock %}
28. Jinja2 的'super'用法 如果你想在子模板里保留父模板的内容,可以用 {{ super() }}:
{% block nav %}
{{ super() }}
<a href ="/help" > 帮助</a >
{% endblock %}
29. Jinja2 的 include 与 with 语法 {% include "user_card.html" with context %}
{% include "user_card.html" with user=user, show_detail=True %}
30. Jinja2 的循环嵌套与 break/continue Jinja2 支持嵌套循环,但不支持 break/continue,可以通过条件控制:
{% for user in users %}
{% if user.is_active %}
<p > {{ user.name }}</p >
{% endif %}
{% endfor %}
31. Jinja2 的 set 用法与复杂表达式 {% set colors = ['red', 'green', 'blue'] %}
{% for color in colors %}
<span > {{ color }}</span >
{% endfor %}
32. Flask 模板自动加载和缓存控制
debug=True 时,模板修改会自动刷新。
生产环境建议关闭 debug,模板会缓存,提升性能。
33. Flask 使用 Blueprint 时的模板组织 your_project/
├── app.py
├── user /
│ ├── __init__.py
│ └── templates/
│ └── user /
│ └── profile.html
from flask import Blueprint, render_template
user_bp = Blueprint('user' , __name__, template_folder='templates' )
@user_bp.route('/profile' )
def profile ():
return render_template('user/profile.html' )
34. 模板中的静态文件版本控制(缓存 bust) <link rel ="stylesheet" href ="{{ url_for('static', filename='style.css', v='20250801') }}" >
35. Jinja2 的自定义全局函数 def greet (name ):
return f'你好,{name} !'
app.jinja_env.globals ['greet' ] = greet
36. Jinja2 的模板继承与 include 的区别
继承 :用于页面整体结构、布局复用(如 base.html)。
include :用于局部片段复用(如导航条、用户卡片)。
37. Jinja2 的'自定义标签'扩展(高级) 如果你需要自定义标签,可以编写 Jinja2 Extension(需要较高水平,一般用不到)。
38. 常见错误与排查方法
模板找不到 :检查路径和文件名,建议用绝对路径或 Blueprint 的 template_folder。
变量未定义 :检查后端传参是否一致。
循环或判断语法错误 :注意 {% %} 和 {{ }} 的区别。
静态文件无法加载 :检查 static 文件夹和 url_for 用法。
中文乱码 :确保模板文件保存为 UTF-8 编码。
39. 实战案例:博客文章列表 @app.route('/blog' )
def blog ():
posts = [
{'title' : '第一篇' , 'author' : '小明' , 'content' : '内容 1' },
{'title' : '第二篇' , 'author' : '小红' , 'content' : '内容 2' },
]
return render_template('blog.html' , posts=posts)
<h2 > 博客列表</h2 >
<ul >
{% for post in posts %}
<li >
<h3 > {{ post.title }}</h3 >
<p > 作者:{{ post.author }}</p >
<div > {{ post.content }}</div >
</li >
{% endfor %}
</ul >
相关免费在线工具 curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online