Flask 模板:使用 Jinja2 渲染 HTML
myzbx 2025-01-24 13:05 18 浏览
Flask 是一个轻量级且灵活的 Python Web 框架。其主要功能之一是能够使用强大的模板引擎 Jinja2 呈现 HTML 模板。本博客将引导您了解 Flask 模板的基础知识,并演示如何使用 Jinja2 渲染动态 HTML 内容。
什么是模板?
Flask 中的模板是包含静态 HTML 以及用于插入动态内容的特殊语法的文件。这些模板通常存储在 Flask 项目目录中名为“templates”的文件夹中。 Flask 使用 Jinja2 作为默认模板引擎,允许您在 HTML 文件中嵌入类似 Python 的表达式和逻辑。
使用 Jinja2 设置 Flask
首先,确保您的 Python 环境中安装了 Flask。您可以使用 pip 安装它:
pip install Flask
接下来,创建一个基本的 Flask 应用程序结构:
flask_app/
│
├── app.py
├── templates/
│ └── index.html
└── static/
创建一个简单的 Flask 应用程序
让我们从一个简单的 Flask 应用程序开始。创建一个名为“app.py”的文件:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html', title="Home Page", message="Welcome to Flask with Jinja2!")
if __name__ == '__main__':
app.run(debug=True)
在此示例中,“render_template”函数呈现“index.html”模板,并传入标题和消息作为变量。
创建您的第一个模板
在项目目录中创建一个名为“templates”的文件夹,并在该文件夹中创建一个名为“index.html”的文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ message }}</h1>
<p>This is a simple Flask application demonstrating Jinja2 templates.</p>
</body>
</html>
在此模板中,“{{ title }}”和“{{ message }}”是占位符,将被从 Flask 路由传递的值替换。
向模板添加逻辑
Jinja2 允许您添加控制结构,例如循环和条件。让我们更新我们的模板来演示这些功能:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ message }}</h1>
<p>This is a simple Flask application demonstrating Jinja2 templates.</p>
<h2>Fruits List:</h2>
<ul>
{% for fruit in fruits %}
<li>{{ fruit }}</li>
{% endfor %}
</ul>
{% if show_greeting %}
<p>Have a great day!</p>
{% else %}
<p>Goodbye!</p>
{% endif %}
</body>
</html>
更新“app.py”以将水果列表和布尔变量传递给模板:
@app.route('/')
def home():
fruits = ["Apple", "Banana", "Cherry", "Date", "Elderberry"]
show_greeting = True
return render_template('index.html', title="Home Page", message="Welcome to Flask with Jinja2!", fruits=fruits, show_greeting=show_greeting)
使用模板继承
模板继承允许您创建具有公共元素(例如页眉和页脚)的基本模板,并在其他模板中扩展它。在“templates”文件夹中创建一个基本模板“base.html”:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Default Title{% endblock %}</title>
</head>
<body>
<header>
<h1>My Website</h1>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
<p>(c) 2024 My Website</p>
</footer>
</body>
</html>
现在,更新“index.html”以扩展“base.html”:
{% extends "base.html" %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<h1>{{ message }}</h1>
<p>This is a simple Flask application demonstrating Jinja2 templates.</p>
<h2>Fruits List:</h2>
<ul>
{% for fruit in fruits %}
<li>{{ fruit }}</li>
{% endfor %}
</ul>
{% if show_greeting %}
<p>Have a great day!</p>
{% else %}
<p>Goodbye!</p>
{% endif %}
{% endblock %}
模板过滤器
Jinja2 允许您使用过滤器在渲染变量之前修改它的值。让我们添加一个自定义过滤器来将列表中的所有项目大写。
在“app.py”中创建自定义过滤器:
from flask import Flask, render_template
app = Flask(__name__)
# Custom filter
def capitalize_list(items):
return [item.capitalize() for item in items]
app.jinja_env.filters['capitalize'] = capitalize_list
@app.route('/')
def home():
fruits = ["apple", "banana", "cherry", "date", "elderberry"]
return render_template('index.html', title="Home Page", message="Welcome to Flask with Jinja2!", fruits=fruits)
if __name__ == '__main__':
app.run(debug=True)
在“index.html”中,将自定义过滤器应用于水果列表:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ message }}</h1>
<p>This is a simple Flask application demonstrating Jinja2 templates.</p>
<h2>Fruits List (Capitalized):</h2>
<ul>
{% for fruit in fruits|capitalize %}
<li>{{ fruit }}</li>
{% endfor %}
</ul>
</body>
</html>
宏
Jinja2 中的宏类似于 Python 中的函数。它们允许您在模板中重复使用代码片段。
在“templates”文件夹中创建一个“macros.html”文件:
{% macro render_fruit_list(fruits) %}
<ul>
{% for fruit in fruits %}
<li>{{ fruit }}</li>
{% endfor %}
</ul>
{% endmacro %}
更新 `index.html` 以使用宏:
{% extends "base.html" %}
{% import "macros.html" as macros %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<h1>{{ message }}</h1>
<p>This is a simple Flask application demonstrating Jinja2 templates.</p>
<h2>Fruits List (Using Macros):</h2>
{{ macros.render_fruit_list(fruits) }}
{% endblock %}
多级模板继承
通过添加另一级别的模板扩展来创建更复杂的模板继承示例。
在“templates”文件夹中创建“layout.html”:
{% extends "base.html" %}
{% block content %}
<div class="container">
{% block body %}{% endblock %}
</div>
{% endblock %}
更新 `index.html` 以扩展 `layout.html`:
{% extends "layout.html" %}
{% block title %}{{ title }}{% endblock %}
{% block body %}
<h1>{{ message }}</h1>
<p>This is a simple Flask application demonstrating Jinja2 templates with multiple levels of inheritance.</p>
<h2>Fruits List:</h2>
<ul>
{% for fruit in fruits %}
<li>{{ fruit }}</li>
{% endfor %}
</ul>
{% if show_greeting %}
<p>Have a great day!</p>
{% else %}
<p>Goodbye!</p>
{% endif %}
{% endblock %}
静态文件
Flask 允许您从“static”目录提供静态文件,例如 CSS、JavaScript 和图像。让我们创建一个简单的样式表并将其包含在我们的模板中。
在项目目录中创建一个名为“static”的文件夹,并添加一个名为“styles.css”的文件:
body {
font-family: Arial, sans-serif;
}
header {
background-color: #f8f9fa;
padding: 20px;
text-align: center;
}
footer {
background-color: #f8f9fa;
padding: 10px;
text-align: center;
position: fixed;
bottom: 0;
width: 100%;
}
更新 `base.html` 以包含样式表:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Default Title{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
<header>
<h1>My Website</h1>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
<p>(c) 2024 My Website</p>
</footer>
</body>
</html>
包含其他模板
有时,您可能希望将模板分解为更小的、可重复使用的部分。 Jinja2 允许您在其他模板中包含模板。
在“templates”文件夹中创建一个“header.html”文件:
<header>
<h1>{{ header_title }}</h1>
</header>
更新 `base.html` 以包含 `header.html`:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Default Title{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
{% include 'header.html' %}
<main>
{% block content %}{% endblock %}
</main>
<footer>
<p>(c) 2024 My Website</p>
</footer>
</body>
</html>
更新 `app.py` 以传递参数作为头标题
@app.route('/')
def home():
fruits = ["apple", "banana", "cherry", "date", "elderberry"]
return render_template('index.html', title="Home Page", message="Welcome to Flask with Jinja2!", fruits=fruits, header_title="Welcome to My Website")
if __name__ == '__main__':
app.run(debug=True)
在本博客中,我们介绍了使用 Jinja2 在 Flask 中渲染 HTML 模板的基础知识。我们创建了一个简单的 Flask 应用程序,构建了动态模板,并利用模板继承来更好地组织。 Flask 和 Jinja2 为开发动态且可维护的 Web 应用程序提供了强大的组合。
通过利用这些工具,您可以使用干净且可重用的代码创建强大且可扩展的 Web 应用程序。祝您快乐编码,关注收藏或者转发给其他小伙伴吧,谢谢!
相关推荐
- C语言备忘录 - 09. 数组与字符串(c语言数组字符串长度)
-
C语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。一、数组定义/*定义一个一维数组数...
- Java 读取 xml 文件的五种方式(java读取xml工具类)
-
1、Java读取xml文件的五种方式在Java中读取XML文件有多种方法,这里列出五种常见的方式:DOM解析器(DocumentObjectModel):DOM是处理XML文...
- 如何获取一个APP的所有接口API和参数签名信息?
-
先给出所需的工具:步骤工具/技术抓包Charles、Fiddler、Wireshark、tcpdump反编译Jadx、JEB、Apktool动态调试Frida、IDAPro、Unidbg/Unico...
- 编辑距离算法详解:Levenshtein Distance算法
-
算法基本原理:假设我们可以使用d[i,j]个步骤(可以使用一个二维数组保存这个值),表示将串s[1…i]转换为串t[1…j]所需要的最少步骤个数,那么,在最基本的情况下,即在i等...
- RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI)
-
RTCP协议规范中定义了五种类型的RTCP包:接收方报告(RR)、发送方报告(SR)、源描述(SDES)、成员管理(BYE)和应用程序定义(APP)。SR:payload...
- javascript实现获取中文汉字拼音首字母
-
今天分享一个日常开发中可能会用到的一个小功能,简单说就是输入中文汉字可转换得到中文汉字拼音首字母。当然我可写不出这样的功能,源码来自于其他民间大神的分享,博主在此记录一下功能demo,方便日后复用,同...
- 记一次前端逻辑绕过登录到内网挖掘
-
前言在测试一个学校网站的时候发现一个未授权访问内网系统,但是这个未授权并不是接口啥的,而是对前端js的审计和调试发现的漏洞,这里给大家分享一下这次的漏洞的过程文章中涉及的敏感信息均已做打码处理,文...
- Node.js 是怎么找到模块的?(node.js有哪些模块)
-
大家好,我是前端西瓜哥,今天我们来看看Node.js模块查找的原理。模块种类模块有三种来源。核心模块:Node.js内置的包。比如http、fs、path;自定义模块:NPM包。比如axi...
- 细节确定成败!全网最详细的xxs夸脚本攻击以及测试方法(上)
-
XSS全称是CrossSiteScripting也是跨站脚本,他也分为三种类型存储型,反射型,DOM型。当目标网站目标用户浏览器渲染HTML文档的过程中,出现了不被预期的脚本指令并执行时,XSS就...
- 简单易懂的KMP字符串匹配算法(实现kmp字符串匹配)
-
什么是KMPKMP算法是Knuth、Morris和Pratt三人设计的线性时间字符串匹配算法。算法的核心思想是尽可能地利用已知信息,减少尝试匹配的次数,从而降低时间复杂度。要想彻底地弄懂KMP算法,需...
- golang标准库每日一库之strings(golang 字符串操作)
-
以下为Go语言strings包的深度解析,涵盖字符串切割、替换、查找等核心操作及高效处理技巧:一、基础字符串操作1.字符串切割(Split)函数作用描述示例strings.Split(s,s...
- 开源轻量级BT下载器qBittorrent 5.1.1发布:改进Wayland会话
-
IT之家6月24日消息,科技媒体9to5Linux昨日(6月23日)发布博文,报道称开源轻量级BT下载器qBittorrent发布5.1.1版本更新,主要改进支持Lin...
- 晨雾轻散时!2 道 JS 面试题细解,静享知识慢时光
-
清晨的雾气渐渐散去,阳光透过纱窗洒在桌前,泡一杯温热的蜂蜜水,让我们在这宁静的氛围里,以轻松的节奏聊聊两道JavaScript高频面试题。就像在晨光中散步,不急不躁地探索知识,让学习成为一种治愈的...
- JS 写正则表达式,判断是否为手机号
-
以下是使用JavaScript写正则表达式,判断一个字符串是否为手机号的示例代码:在上述代码中,我们定义了一个isPhoneNumber函数,该函数接收一个字符串作为参数,使用正则表达式判断该...
- 不用任何 js 库,纯前端导出数据到 Excel / CSV 文件就简单几行代码
-
最近实现的导出数据为表格的需求,不需要工具库,也不要后端实现,mark一下。js导出excel表格最近工作中又遇到了将表格数据导出为excel表格的需求,我第一时间想到的是之前我的网站上推...
- 一周热门
- 最近发表
-
- C语言备忘录 - 09. 数组与字符串(c语言数组字符串长度)
- Java 读取 xml 文件的五种方式(java读取xml工具类)
- 如何获取一个APP的所有接口API和参数签名信息?
- 编辑距离算法详解:Levenshtein Distance算法
- RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI)
- javascript实现获取中文汉字拼音首字母
- 记一次前端逻辑绕过登录到内网挖掘
- Node.js 是怎么找到模块的?(node.js有哪些模块)
- 细节确定成败!全网最详细的xxs夸脚本攻击以及测试方法(上)
- 简单易懂的KMP字符串匹配算法(实现kmp字符串匹配)
- 标签列表
-
- HTML 简介 (30)
- HTML 响应式设计 (31)
- HTML URL 编码 (32)
- HTML Web 服务器 (31)
- HTML 表单属性 (32)
- HTML 音频 (31)
- HTML5 支持 (33)
- HTML API (36)
- HTML 总结 (32)
- HTML 全局属性 (32)
- HTML 事件 (31)
- HTML 画布 (32)
- HTTP 方法 (30)
- 键盘快捷键 (30)
- CSS 语法 (35)
- CSS 选择器 (30)
- CSS 轮廓宽度 (31)
- CSS 谷歌字体 (33)
- CSS 链接 (31)
- CSS 定位 (31)
- CSS 图片库 (32)
- CSS 图像精灵 (31)
- SVG 文本 (32)
- 时钟启动 (33)
- HTML 游戏 (34)