Python 简明教程

Python - Templating

Templating in Python

Python 中的模板编制是在 Web 开发中用来使用模板和数据动态生成静态 HTML 页面的技术。

在本教程中,我们将探讨 Python 中模板编制的要点,包括安装、创建模板以及使用数据渲染模板,重点讲述 Jinja2 模板引擎。

String Templates in Python

Python 中的字符串模板是执行字符串替换的一种简单方法。Python 的字符串模块包含 Template class,它提供一种简单的方法,可以用实际值替换字符串中的占位符。

模板字符串使用 $ 符号进行替换,紧随其后的是一个标识符,它遵循形成有效 Python 标识符的规则。

Creating a Template

要创建一个模板,可以使用一个包含占位符的字符串实例化 Template class,占位符添加 $ 前缀,如下所示 −

from string import Template

template = Template("Hello, $name!")

Substituting Values

可以使用 substitute() 方法来将值代入模板,此方法采用一个键值对字典。

substitute() 方法用实际值替换模板中的占位符(标识符)。可以使用关键字参数或字典提供这些值。该方法返回一个新的字符串,其中占位符已填入。

Example: Using Keyword Arguments

以下代码通过关键字参数替换模板字符串中的标识符 −

from string import Template

tempStr = Template('Hello. My name is $name and my age is $age')
newStr = tempStr.substitute(name = 'Pushpa', age = 26)
print (newStr)

它将生成如下输出:

Hello. My name is Pushpa and my age is 26

Example: Using a Dictionary

在以下示例中,使用一个字典对象将模板字符串中的替换标识符映射 −

from string import Template

tempStr = Template('Hello. My name is $name and my age is $age')
dct = {'name' : 'Pushpalata', 'age' : 25}
newStr = tempStr.substitute(dct)
print (newStr)

以下是上面代码的输出: -

Hello. My name is Pushpalata and my age is 25

Example: Missing Parameters Raises KeyError

如果未向 substitute() 方法提供足够的参数来匹配模板字符串中的标识符,Python 将引发 KeyError −

from string import Template

tempStr = Template('Hello. My name is $name and my age is $age')
dct = {'name' : 'Pushpalata'}
newStr = tempStr.substitute(dct)
print (newStr)

以下错误已生成 −

Traceback (most recent call last):
  File "/home/cg/root/667e441d9ebd5/main.py", line 5, in <module>
newStr = tempStr.substitute(dct)
  File "/usr/lib/python3.10/string.py", line 121, in substitute
    return self.pattern.sub(convert, self.template)
  File "/usr/lib/python3.10/string.py", line 114, in convert
return str(mapping[named])
KeyError: 'age'

Substituting Values Using safe_substitute() Method

safe_substitute() 方法的行为类似于 substitute() 方法,不同之处在于,如果键不足或不匹配,它不会引发错误。相反,原始占位符将原封不动地出现在结果字符串中。

Example

在以下示例中,使用 safe_substitue() 方法来替换值 −

from string import Template
tempStr = Template('Hello. My name is $name and my age is $age')
dct = {'name' : 'Pushpalata'}
newStr = tempStr.safe_substitute(dct)
print (newStr)

它将生成如下输出:

Hello. My name is Pushpalata and my age is $age

Installing Jinja2

要在 Python 中使用 Jinja2 进行模板编制,首先需要安装库。Jinja2 是一个强大的模板引擎,在 Web 开发中被广泛用来渲染 HTML。可以使用 Python 的包安装器 pip 轻松安装该引擎 −

pip install jinja2

Creating and Rendering Jinja2 Templates

Jinja2 是 Python 中强大的模板引擎,它允许通过将静态模板文件和数据融合来创建动态内容。本节将探讨如何创建 Jinja2 模板,并使用数据渲染它们。

Creating a Jinja2 Template

要创建 Jinja2 模板,需要定义一个模板字符串或从文件中加载。模板使用双花括号 {{ …​ }} 作为占位符,并使用 {% …​ %} 支持“循环”和“条件”等控制结构。

Example

以下是一个存储在“template.html”文件中的简单的 Jinja2 模板示例 −

<!DOCTYPE html>
<html>
<head>
    <title>Hello, {{ name }}!</title>
</head>
<body>
    <h1>Hello, {{ name }}!</h1>
    <p>Welcome to our site.</p>
</body>
</html>

Rendering a Jinja2 Template

要呈现 Jinja2 模板,请按以下步骤操作 −

  1. Loading the Template − 从文件中加载模板或从字符串创建模板。

  2. Creating a Template Object − 使用“jinja2.Template”创建模板对象。

  3. Rendering − 在模板对象中使用 render() 方法,以数据作为参数或字典传递。

Example

在此处,我们正在渲染 Jinja2 模板 −

from jinja2 import Template, FileSystemLoader, Environment

# Loading a template from a file (template.html)
file_loader = FileSystemLoader('.')
env = Environment(loader=file_loader)
template = env.get_template('template.html')

# Rendering the template with data
output = template.render(name='Alice')

# Output the rendered template
print(output)

呈现的 Jinja2 模板的输出将是一个 HTML 文档,其中占位符将替换为呈现期间传递的实际数据 −

<!DOCTYPE html>
<html>
<head>
    <title>Hello, Alice!</title>
</head>
<body>
    <h1>Hello, Alice!</h1>
    <p>Welcome to our site.</p>
</body>
</html>

Advanced Jinja2 Features

Template Inheritance

Jinja2 支持模板继承,允许你创建一个使用常见元素(如标题、页脚、导航栏)的基础模板,并在子模板中扩展或覆盖特定块。这促进了大型项目中的代码重用和可维护性。

Example

此名为“base.html”的 HTML 模板文件使用 Jinja2 模板语法为网页定义了一个基本结构。

它包括块“{% block title %}"和“{% block content %}",可以在派生模板中覆盖这些块,以分别自定义页面的标题和主要内容 −

<!-- base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}Default Title{% endblock %}</title>
</head>
<body>
    {% block content %}{% endblock %}
</body>
</html>

以下 Jinja2 模板文件“child.html”扩展了“base.html”模板,覆盖标题块以将其设置为“子页面”,并将内容块覆盖为包含文本“子页面内容”的 <h1> 标题。

<!-- child.html -->
{% extends "base.html" %}

{% block title %}Child Page{% endblock %}

{% block content %}
<h1>Child Page Content</h1>
{% endblock %}

Loops

Jinja2 允许你使用 {% for %} 循环来遍历列表或其他可迭代对象。以下是如何使用循环在 HTML 中生成无序列表 (<ul>) 的示例 −

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

Conditionals

Jinja2 ({% if %}{% else %}) 中的条件语句用于根据条件控制你的模板的流。这里有一个“Jinja2”检查用户是否存在,如果存在,则显示个性化问候语的示例;否则,提示用户登录 −

{% if user %}
    <p>Welcome, {{ user }}!</p>
{% else %}
    <p>Please log in.</p>
{% endif %}

Custom Filters

Jinja2 中的自定义过滤器用于定义你自己的过滤器,以便在模板中显示之前操作数据。

在以下示例中,在 Jinja2 中定义了一个自定义过滤器 reverse 来反转字符串“hello”,在模板中应用时会转换成“olleh” −

# Define a custom filter function
def reverse_string(s):
    return s[::-1]

# Register the filter with the Jinja2 environment
env.filters['reverse'] = reverse_string

然后在你的模板中,你可以将“reverse”过滤器应用到任何字符串 −

{{ "hello" | reverse }}

以下是所获得的输出 −

olleh