尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Flask入门教程(九):模板渲染——用Jinja2构建动态页面

Flask入门教程(九):模板渲染——用Jinja2构建动态页面 1. render_template基础render_template()是Flask中最常用的模板渲染函数。它的第一个参数是模板文件名后面的关键字参数会作为变量传递给模板。# 文件路径app.py from flask import Flask, render_template app Flask(__name__) app.route(/) def index(): return render_template(index.html, titleRUNOOB 首页, nameWorld) app.route(/user/username) def profile(username): return render_template(user.html, usernameusername, posts[ {title: Flask 入门, date: 2026-05-01}, {title: Jinja2 模板, date: 2026-05-10}, ])模板文件放在项目目录下的templates/文件夹中runoob-flask-test/ ├── app.py └── templates/ ├── index.html └── user.htmltemplates/index.html!DOCTYPE html html head title{{ title }} - RUNOOB/title /head body h1{{ title }}/h1 pHello {{ name }}。/p /body /html2. Jinja2基础语法Jinja2模板中三种核心语法语法用途示例{{ ... }}输出变量值自动转义HTML{{ username }}{% ... %}控制语句if、for、block等{% if user %}{# ... #}注释不会出现在渲染结果中{# 这是注释 #}模板示例条件判断与循环templates/user.html!DOCTYPE html html head title{{ username }} - RUNOOB/title /head body h1{{ username }} 的个人主页/h1 !-- 条件判断 -- {% if posts %} h2最近文章/h2 ul !-- 循环遍历 -- {% for post in posts %} li{{ loop.index }}. {{ post.title }} ({{ post.date }})/li {% endfor %} /ul {% else %} p暂无文章/p {% endif %} !-- 使用过滤器 -- p用户名大写{{ username|upper }}/p /body /html3. 常用过滤器过滤器用于修改变量的输出格式使用管道符|调用。过滤器作用示例输出upper转大写{{ hello|upper }}HELLOlower转小写{{ HELLO|lower }}hellotitle首字母大写{{ hello world|title }}Hello Worldlength获取长度{{ [1,2,3]|length }}3default设置默认值{{ name|default(匿名) }}匿名当name为空时safe标记为安全HTML不转义{{ b粗体/b|safe }}渲染为粗体文字join连接列表{{ [a,b]|join(,) }}a,b⚠️安全警告safe过滤器会关闭自动转义只在绝对信任数据来源时使用。对于用户输入的内容永远不要使用safe。4. 自动转义——XSS防护Jinja2默认会对所有变量输出进行HTML转义这是Web安全的一道关键防线。例如如果用户提交的用户名是scriptalert(xss)/script模板渲染时会自动转换为安全文本!-- 模板中直接使用变量 -- p{{ username }}/p !-- 渲染结果HTML特殊字符已被转义 -- lt;pgt;amp;lt;scriptamp;gt;alert(amp;quot;xssamp;quot;)amp;lt;/scriptamp;gt;lt;/pgt;转义适用于.html、.htm、.xml、.xhtml、.svg结尾的模板文件。5. 模板继承——消除重复代码模板继承是Jinja2最强大的功能之一它让你可以定义一个「基础布局」然后通过子模板填充内容。这避免了在每个页面中重复编写头部、导航、页脚等公共部分。基础模板父模板templates/base.html!DOCTYPE html html head meta charsetutf-8 title{% block title %}RUNOOB Flask 教程{% endblock %}/title link relstylesheet href{{ url_for(static, filenamestyle.css) }} /head body header h1RUNOOB Flask 教程/h1 nav a href/首页/a | a href/about关于/a /nav /header main {% block content %}{% endblock %} /main footer pcopy; 2026 RUNOOB.com/p /footer /body /html子模板继承父模板templates/index.html{% extends base.html %} {% block title %}RUNOOB 教程 - 首页{% endblock %} {% block content %} h2欢迎来到 RUNOOB/h2 p{{ greeting }}/p {% if user %} p当前用户{{ user }}/p {% else %} pa href/login请先登录/a/p {% endif %} {% endblock %}标签作用{% extends base.html %}声明当前模板继承自base.html必须放在第一行{% block name %}...{% endblock %}定义一个可被子模板覆盖的区域{{ super() }}在子模板block中调用父模板同名block的内容使用模板继承后你只需要修改base.html一处所有页面的公共部分如导航、页脚都会自动更新。6. 模板中的内置对象以下Flask对象在模板中可以直接使用无需通过render_template()传递对象说明模板中使用示例request当前请求对象{{ request.path }}session当前会话数据{{ session.get(username) }}g请求级全局变量{{ g.user }}config应用配置{{ config[APP_NAME] }}url_for()URL生成函数{{ url_for(index) }}get_flashed_messages()获取flash消息{% for msg in get_flashed_messages() %}7. 包含其他模板——include使用{% include %}可以在一个模板中嵌入另一个模板适用于导航栏、侧边栏等可复用组件。templates/_navbar.html下划线开头表示这是一个局部模板nav stylebackground:#f0f0f0;padding:10px; a href/首页/a | a href/posts文章/a | a href/about关于/a /nav在任意模板中引入!DOCTYPE html html headtitle页面/title/head body {% include _navbar.html %} h1页面内容/h1 p这是页面主体内容。/p /body /html最佳实践模板继承extends用于页面级的布局复用include用于组件级的代码复用。8. 完整示例博客首页app.pyfrom flask import Flask, render_template app Flask(__name__) app.route(/) def index(): articles [ {id: 1, title: Flask 入门指南, author: runoob, views: 1024}, {id: 2, title: Jinja2 模板详解, author: admin, views: 512}, {id: 3, title: RESTful API 设计, author: runoob, views: 256}, ] return render_template(blog.html, articlesarticles)templates/blog.html{% extends base.html %} {% block title %}RUNOOB 博客{% endblock %} {% block content %} h2最新文章/h2 {% if articles %} {% for article in articles %} div classarticle {% if article.views 1000 %}stylebackground:#fff3cd;{% endif %} h3{{ article.title }}/h3 p作者{{ article.author }} | 浏览{{ article.views }}/p {% if not loop.last %} hr {% endif %} /div {% endfor %} {% else %} p暂时没有文章请稍后再来。/p {% endif %} {% endblock %}9. Jinja2循环特殊变量在{% for %}循环中Jinja2提供了以下内置变量变量说明loop.index当前循环索引从1开始loop.index0当前循环索引从0开始loop.first是否为第一次循环loop.last是否为最后一次循环loop.length序列总长度10. 模板语法速查表用途语法示例变量输出{{ variable }}{{ username }}变量输出带默认值{{ variable|default(默认) }}{{ name|default(匿名) }}条件判断{% if condition %}...{% endif %}{% if user %}条件判断多分支{% if %}...{% elif %}...{% else %}...{% endif %}同上循环遍历{% for item in list %}...{% endfor %}{% for post in posts %}循环空时{% for %}...{% else %}...{% endfor %}列表为空时显示备用内容模板继承{% extends base.html %}必须放在第一行定义块{% block name %}...{% endblock %}{% block content %}包含模板{% include partial.html %}组件复用注释{# 注释内容 #}不会出现在渲染结果中小结本章全面讲解了Flask的模板渲染系统。render_template()是渲染模板的核心函数Jinja2的{{ }}用于变量输出自动转义防XSS{% %}用于控制语句if判断、for循环过滤器通过|修改变量输出格式模板继承通过{% extends %}和{% block %}消除重复代码实现页面级布局复用{% include %}实现组件级复用模板中可直接使用request、session、url_for()等内置对象。模板引擎让业务逻辑与页面展示分离是构建动态Web应用的关键工具。
返回列表