当前位置: 首页 > news >正文

Flask(四) 模板渲染render_template

文章目录

  • 📦 过程详解(路由 <-> HTML 模板)
    • 🧠 数据是怎么传过去的?
    • 多变量示例
  • ✅ Jinja2 支持条件判断、循环、模板继承:
  • ✅ 安全性
    • 🔒 Flask 默认也会对变量进行 HTML 转义:
    • 📍 {{ chart | safe }}
      • 在 pyecharts 中怎么用?
  • 📦模板继承
    • 🧱 文件结构示例
      • base.html(母板模板)
      • index.html(子模板)
      • login.html(子模板)
  • 📦过滤器
  • 📦宏和模板包含

Flask 使用 Jinja2 模板引擎来处理模板渲染。模板渲染允许你将动态内容插入到 HTML 页面中,使得应用能够生成动态的网页内容。

  • 创建模板:将 HTML 文件放在 templates 文件夹中,使用 Jinja2 占位符。
  • 渲染模板:使用 render_template 函数在视图函数中渲染模板。
  • 模板继承:创建基础模板,允许其他模板继承和扩展。
  • 控制结构:使用条件语句和循环在模板中控制逻辑。
  • 过滤器:使用过滤器格式化变量数据。
  • 宏和模板包含:创建和使用宏以及模板包含,提高模板的复用性。
  • 安全性:Jinja2 默认对模板变量进行自动转义以防止 XSS 攻击。
  • 模板上下文:将数据传递给模板,并在模板中使用这些数据。

📦 过程详解(路由 <-> HTML 模板)

浏览器请求:GET /hello↓
Flask 匹配 @app.route('/hello') → 调用 hello() 函数↓
hello() 中使用 render_template() 渲染 hello.html↓
将 name="张三" 传入模板引擎 Jinja2↓
Jinja2 渲染出 HTML: <h1>你好, 张三!</h1>↓
Flask 把 HTML 打包成 Response 对象返回浏览器↓
浏览器显示页面

🧠 数据是怎么传过去的?

render_template("模板名.html", 变量名1=1, 变量名2=2, ...)

模板中用 {{ 变量名 }} 就能访问到。

多变量示例

@app.route('/dashboard')
def dashboard():stats = {"pv": 1000, "uv": 300}return render_template('dashboard.html', stats=stats, username="admin")

templates/dashboard.html

<h2>欢迎, {{ username }}</h2>
<p>页面浏览量:{{ stats.pv }}</p>
<p>独立访客数:{{ stats.uv }}</p>

✅ Jinja2 支持条件判断、循环、模板继承:

{% if user %}<p>欢迎 {{ user }}!</p>
{% else %}<p>请先登录</p>
{% endif %}

{% if user %}:检查 user 变量是否存在,如果存在,则显示欢迎消息,否则显示登录提示。

循环语句:

<ul>
{% for item in items %}<li>{{ item }}</li>
{% endfor %}
</ul>

{% for item in items %}:遍历 items 列表,并为每个项生成一个 <li> 元素。

✅ 安全性

自动转义:Jinja2 默认会对模板中的变量进行自动转义,防止 XSS 攻击。
{{ user_input }}:用户输入的内容会被自动转义,以避免恶意脚本的注入。

🔒 Flask 默认也会对变量进行 HTML 转义:

比如

chart = "<script>alert('Hi')</script>"

在模版中写

{{ chart }}

浏览器会看到:

&lt;script&gt;alert('Hi')&lt;/script&gt;

因为 Flask 模板会自动进行 HTML 安全转义。

📍 {{ chart | safe }}

{{ chart | safe }} 是 Flask 模板中一个非常常见的写法,特别用于像 pyecharts、plotly 等图表库,把图表插入 HTML 页面的关键语句。
{{ chart | safe }} 意思是把 chart 的内容作为 HTML 原样输出(不再自动转义)

在 pyecharts 中怎么用?

pyecharts 生成的图表是一个 HTML

from pyecharts.charts import Bar
from pyecharts import options as optsbar = (Bar().add_xaxis(["A", "B", "C"]).add_yaxis("销量", [10, 20, 30])
)
chart = bar.render_embed()

在 Flask 中渲染:

return render_template("chart.html", chart=chart)

模板中这样写:

<div>{{ chart | safe }}
</div>

这样图表就会在页面中正常显示!

请不要对用户输入的数据使用 | safe,除非你已经对内容做过严格校验,否则可能产生 XSS 攻击漏洞。

📦模板继承

模板继承允许你创建一个基础模板,然后在其他模板中继承和扩展这个基础模板,避免重复的 HTML 代码。

创建基础模板:在 templates 文件夹中创建一个基础模板 base.html。

templates/base.html 示例:

<!DOCTYPE html>
<html>
<head><title>{% block title %}My Website{% endblock %}</title>
</head>
<body><header><h1>My Website</h1></header><main>{% block content %}{% endblock %}</main><footer><p>Footer content</p></footer>
</body>
</html>

{% block title %} {% endblock %} {% block content %} {% endblock %} 是定义的可替换区域。
创建子模板:在 templates 文件夹中创建一个子模板 index.html,继承 base.html。

templates/index.html 文件代码:

{% extends "base.html" %}{% block title %}Home Page{% endblock %}{% block content %}
<h2>Welcome to the Home Page!</h2>
<p>Content goes here.</p>
{% endblock %}

{% extends "base.html" %}:继承基础模板。

{% block title %} {% block content %}:重写基础模板中的块内容。

🧱 文件结构示例

templates/
├── base.html        ← 通用母版模板
├── index.html       ← 首页(继承 base)
└── login.html       ← 登录页(继承 base

base.html(母板模板)

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>{% block title %}默认标题{% endblock %}</title><link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body><header><h1>我的网站</h1><nav><a href="{{ url_for('index') }}">首页</a> |<a href="{{ url_for('login') }}">登录</a></nav></header><main>{% block content %}{% endblock %}</main><footer><p>版权所有 © 2025</p></footer>
</body>
</html>

index.html(子模板)

{% extends "base.html" %}{% block title %}首页{% endblock %}{% block content %}
<h2>欢迎访问首页</h2>
<p>这里是首页内容</p>
{% endblock %}

login.html(子模板)

{% extends "base.html" %}{% block title %}登录{% endblock %}{% block content %}
<h2>登录页面</h2>
<form method="post">用户名: <input name="username"><br>密码: <input name="password" type="password"><br><button type="submit">登录</button>
</form>
{% endblock %}

📦过滤器

过滤器用于在模板中格式化和处理变量数据。

<p>{{ name|capitalize }}</p>
<p>{{ price|round(2) }}</p>

{{ name|capitalize }}:将 name 变量的值首字母大写。
{{ price|round(2) }}:将 price 变量的值四舍五入到小数点后两位。

📦宏和模板包含

宏是可重用的模板片段。模板包含允许你在一个模板中插入另一个模板的内容。
创建宏

templates/macros.html 代码文件:
实例
{% macro render_item(item) %}<div><h3>{{ item.title }}</h3><p>{{ item.description }}</p></div>
{% endmacro %}

使用宏:

templates/index.html 文件代码:
实例

{% from "macros.html" import render_item %}<h1>Items</h1>
{% for item in items %}{{ render_item(item) }}
{% endfor %}

{% from "macros.html" import render_item %}:导入宏。
{{ render_item(item) }}:调用宏来渲染每个 item。

http://www.lryc.cn/news/574632.html

相关文章:

  • Dify×奇墨科技:开源+本土化,破解企业AI落地难题
  • Chrome MCP Server:AI驱动浏览器自动化测试实战「喂饭教程」
  • iframe窗体默认白色背景去除
  • 重点解析(软件工程)
  • 云电脑,“死”于AI时代前夕 | 数智化观察
  • 基于DE1-SoC的My_First_oneAPI(二)
  • 黑马Day01-03集开始
  • 第24篇:Linux内核深度解析与OpenEuler 24.03实践指南
  • TCP/UDP协议深度解析(一):UDP特性与TCP确认应答以及重传机制
  • 交易期权先从买方开始
  • C8BJWD8BJV美光固态闪存HSA22HSA29
  • android脱糖
  • Kubernetes生命周期管理:深入理解 Pod 生命周期
  • python有哪些常用的GUI(图形用户界面)库及选择指南
  • Unity Text-Mesh Pro无法显示中文的问题
  • Android检测当前进程或者应用是否被调试
  • 安卓android com.google.android.material.tabs.TabLayout 设置下拉图标无法正常显示
  • 国产化条码类库Spire.Barcode教程:如何使用 C# 读取 PDF 中的条码(两种方法轻松实现)
  • 【数字后端】- 什么是NDR规则?
  • vscode打开.c文件后中文乱码
  • ros(一)使用消息传递图像+launch启动文件
  • 通过Prompt提示构建思维链
  • git操作练习(3)
  • WHAT - React Native 的 Expo Router
  • 华为云Flexus+DeepSeek征文|华为云ModelArts Studio:利用New API实现大模型网关与AI资产管理的无缝对接
  • 梳理React中的fiber架构
  • 学历信息查询API (IVYZ9A2B) 的对接实战 | 天远API
  • WPF/Net Core 简单显示PDF
  • WEB安全--Java安全--jsp webshell免杀1
  • 原子操作(CAS)