---
title: "模板"
version: 4.0
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/4.0/topics/templates/
canonical: https://djangodocs.dev/zh-hans/4.0/topics/templates/
---
# 模板

作为一个网络框架，Django 需要一种方便的方式来动态生成 HTML。最常见的方法是依靠模板。一个模板包含了所需 HTML 输出的静态部分，以及一些特殊的语法，描述了如何插入动态内容。关于使用模板创建 HTML 页面的实战例子，请看 [教程 3](/zh-hans/4.0/intro/tutorial03/)。

一个 Django 项目可以配置一个或多个模板引擎（如果你不使用模板，甚至可以不配置模板）。Django 内置了自己的模板系统后端，创造性地称为 Django 模板语言（DTL），以及流行的替代版本 [Jinja2](https://jinja.palletsprojects.com/)。其他模板语言的后端可以从第三方获得。你也可以编写自己的自定义后端，参见：[自定义模板后端](/zh-hans/4.0/howto/custom-template-backend/)

Django 定义了一个标准的API，用于加载和渲染模板，而不考虑后端。加载包括为给定的标识符找到模板并对其进行预处理，通常是将其编译成内存中的表示形式。渲染是指将上下文数据插入模板，并返回结果字符串。

[Django 模板语言](/zh-hans/4.0/ref/templates/language/) 是 Django 自己的模板系统。在 Django 1.8 之前，它是唯一的内置选项。它是一个很好的模板库，尽管它是相当有主见的，并且有一些特殊的地方。如果你没有迫切的理由选择另一个后端，你应该使用 DTL，特别是当你正在编写一个可插拔的应用程序，并且你打算发布模板时。Django 的 contrib 应用如果包含模板，比如 [django.contrib.admin](/zh-hans/4.0/ref/contrib/admin/)，就使用 DTL。

由于历史原因，模板引擎的通用支持和 Django 模板语言的实现都在 `django.template` 的命名空间中。

> **Warning**
>
> 模板系统对于不受信任的模板作者并不安全。例如，一个网站不应该允许其用户提供自己的模板，因为模板作者可以做一些事情，如执行 XSS 攻击和访问可能包含敏感信息的模板变量的属性。

## Django 模板语言

### 语法

> **关于本节**
>
> 这是对 Django 模板语言语法的概述。详细信息请参见 [语言语法参考](/zh-hans/4.0/ref/templates/language/)。

Django 模板是使用 Django 模板语言标记的一个文本文档或Python字符串。模板引擎可以识别和解释一些构造。主要是变量和标签。

模板是通过上下文来渲染的。渲染用变量的值替换变量，变量的值在上下文中查找，并执行标签。其他的一切都按原样输出。

Django 模板语言的语法涉及四个构造。

#### 变量

变量从上下文中输出一个值，上下文是一个类似于字典的对象，将键映射到值。

变量被 `{{` 和 `}}` 包围，如下所示：

```html+django
My first name is {{ first_name }}. My last name is {{ last_name }}.
```

在上下文为 `{'first_name': 'John', 'last_name': 'Doe'}` 的情况下，该模板渲染为：

```html+django
My first name is John. My last name is Doe.
```

字典查找，属性查找和列表索引查找均以点符号实现：

```html+django
{{ my_dict.key }}
{{ my_object.attribute }}
{{ my_list.0 }}
```

如果变量解析为可调用对象，则模板系统将不带任何参数的情况下调用它，并使用其结果代替可调用对象。

#### 标签

标签在渲染过程中提供了任意逻辑。

这个定义是故意含糊的。例如，标签可以输出内容，或用作控制结构如 “if” 语句和 “for” 循环，或从数据库中抓取内容，甚至可以访问其他模板标签。

标签被 `{%` 和 `%}` 包围，如下所示：

```html+django
{% csrf_token %}
```

大多数标签都接受参数：

```html+django
{% cycle 'odd' 'even' %}
```

一些标签需要开始和结束标签：

```html+django
{% if user.is_authenticated %}Hello, {{ user.username }}.{% endif %}
```

提供 [内置标签参考](/zh-hans/4.0/ref/templates/builtins/#ref-templates-builtins-tags) 以及 [自定义标签编写指南](/zh-hans/4.0/howto/custom-template-tags/#howto-writing-custom-template-tags)。

#### 过滤器

过滤器转换变量和标签参数的值。

它们看起来像这样：

```html+django
{{ django|title }}
```

在 `{'django': 'the web framework for perfectionists with deadlines'}` 的上下文中，这个模板渲染为：

```html+django
The Web Framework For Perfectionists With Deadlines
```

有些过滤器需要一个参数：

```html+django
{{ my_date|date:"Y-m-d" }}
```

提供 [内建过滤器参考](/zh-hans/4.0/ref/templates/builtins/#ref-templates-builtins-filters) 以及 [自定义过滤器编写指南](/zh-hans/4.0/howto/custom-template-tags/#howto-writing-custom-template-filters).

#### Comments

注释看起来像这样：

```html+django
{# this won't be rendered #}
```

[`{% comment %}`](/zh-hans/4.0/ref/templates/builtins/#std-templatetag-comment) 标签提供多行注释。

### 组件

> **关于本节**
>
> 这是对 Django 模板语言 API 的概述。详细信息请参见 [API 参考](/zh-hans/4.0/ref/templates/api/)。

#### 引擎

[`django.template.Engine`](/zh-hans/4.0/ref/templates/api/#django.template.Engine) 封装了 Django 模板系统的实例。直接实例化 [`Engine`](/zh-hans/4.0/ref/templates/api/#django.template.Engine) 的主要原因是为了在 Django 项目之外使用 Django 模板语言。

[`django.template.backends.django.DjangoTemplates`](#django.template.backends.django.DjangoTemplates) 是一个简单封装，使 [`django.template.Engine`](/zh-hans/4.0/ref/templates/api/#django.template.Engine) 适应 Django 的模板后端API。

#### 模板

[`django.template.Template`](/zh-hans/4.0/ref/templates/api/#django.template.Template) 代表已编译的模板。模板可以通过 [`Engine.get_template()`](/zh-hans/4.0/ref/templates/api/#django.template.Engine.get_template) 或 [`Engine.from_string()`](/zh-hans/4.0/ref/templates/api/#django.template.Engine.from_string) 获得。

同样 `django.template.backends.django.Template` 是一个简单封装，使 [`django.template.Template`](/zh-hans/4.0/ref/templates/api/#django.template.Template) 适应通用模板 API。

#### 上下文

[`django.template.Context`](/zh-hans/4.0/ref/templates/api/#django.template.Context) 除了上下文数据外，还保存了一些元数据。它被传递给 [`Template.render()`](/zh-hans/4.0/ref/templates/api/#django.template.Template.render) 来渲染模板。

[`django.template.RequestContext`](/zh-hans/4.0/ref/templates/api/#django.template.RequestContext) 是 [`Context`](/zh-hans/4.0/ref/templates/api/#django.template.Context) 的子类，它储存当前的 [`HttpRequest`](/zh-hans/4.0/ref/request-response/#django.http.HttpRequest) 并运行模板上下文处理器。

通用 API 没有对应的概念。上下文数据以普通的 [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) 传递，而当前的 [`HttpRequest`](/zh-hans/4.0/ref/request-response/#django.http.HttpRequest) 则根据需要单独传递。

#### 加载器

模板加载器负责定位模板，加载模板，并返回 [`Template`](/zh-hans/4.0/ref/templates/api/#django.template.Template) 对象。

Django 提供了几个 [内建模板加载器](/zh-hans/4.0/ref/templates/api/#template-loaders) 并且支持 [自定义模板加载器](/zh-hans/4.0/ref/templates/api/#custom-template-loaders)。

#### 上下文处理器

上下文处理器是接收当前的 [`HttpRequest`](/zh-hans/4.0/ref/request-response/#django.http.HttpRequest) 作为参数，并返回一个 [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) 的数据添加到渲染上下文的函数。

它们的主要用途是将所有模板共享的通用数据添加到上下文中，而无需在每个视图中重复代码。

Django 提供了许多 [内置上下文处理器](/zh-hans/4.0/ref/templates/api/#context-processors)，你也可以实现自己的其他上下文处理器。

## 模板引擎的支持

### 配置

模板引擎是通过 [`TEMPLATES`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES) 进行配置。这是一个配置列表，每个引擎都有一个。默认值为空。[`startproject`](/zh-hans/4.0/ref/django-admin/#django-admin-startproject) 命令生成的 `settings.py`  定义了一个更有用的值：

```python
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            # ... some options here ...
        },
    },
]
```

[`BACKEND`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-BACKEND) 是实现 Django 模板后端 API 的模板引擎类的点分隔 Python 路径。内置的后端有 [`django.template.backends.django.DjangoTemplates`](#django.template.backends.django.DjangoTemplates) 和 [`django.template.backends.jinja2.Jinja2`](#django.template.backends.jinja2.Jinja2)。

由于大多数引擎都是从文件中加载模板，因此每个引擎的顶层配置都包含两个常见的配置：

- [`DIRS`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-DIRS) 定义了目录列表，引擎应在其中按搜索顺序查找模板源文件。
- [`APP_DIRS`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-APP_DIRS) 告诉引擎是否应该在已安装的应用程序中寻找模板。每个后端都为应用程序中存储模板的子目录定义了一个惯用名称。

虽然不常见，但可以使用不同的选项配置同一后端的多个实例。 在这种情况下，你应该为每个引擎定义一个唯一的 [`NAME`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-NAME)。

[`OPTIONS`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-OPTIONS) 包含特定于后端的配置。

### 用法

`django.template.loader` 模块定义了两个加载模板的函数。

#### `get_template(template_name, using=None)`

此函数使用给定名称加载模板并返回 `Template` 对象。

返回值的确切类型取决于加载模板的后端。 每个后端都有自己的 `Template` 类。

`get_template()` 依次尝试每个模板引擎，直到成功为止。如果找不到模板，则会引发 [`TemplateDoesNotExist`](#django.template.TemplateDoesNotExist) 错误。如果找到模板但包含无效语法，则会引发 [`TemplateSyntaxError`](#django.template.TemplateSyntaxError) 错误。

搜索和加载模板的方式取决于每个引擎的后端和配置。

如果你想把搜索限制在一个特定的模板引擎上，在 `using` 参数中传递该引擎的 [`NAME`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-NAME)。

#### `select_template(template_name_list, using=None)`

`select_template()` 就像 `get_template()`，不同的是，它接受一个模板名称的列表。它按顺序尝试每个名字，并返回第一个存在的模板。

如果加载模板失败，则可能会引发在 `django.template` 中定义的以下两个异常：

#### `exception TemplateDoesNotExist(msg, tried=None, backend=None, chain=None)`

当找不到模板时引发此异常。 它接受以下可选参数在调试页面上填充 [模板事后检验](/zh-hans/4.0/howto/custom-template-backend/#template-postmortem) ：

**`backend`**

  产生异常的模板后端实例。

**`tried`**

  查找模板时尝试过的来源列表。它的格式为包含 `(origin, status)` 的元组列表，其中 `origin` 是一个 [类 origin](/zh-hans/4.0/howto/custom-template-backend/#template-origin-api) 对象而 `status` 是一个说明找不到模板原因的字符串。

**`chain`**

  尝试加载模板时引发的一系列中间 [`TemplateDoesNotExist`](#django.template.TemplateDoesNotExist) 异常列表。这由函数使用，例如：[`get_template()`](#django.template.loader.get_template)，这些函数尝试从多个引擎加载给定的模板。

#### `exception TemplateSyntaxError(msg)`

当找到模板但包含错误时，将引发此异常。

由 `get_template()` 和 `select_template()` 返回的 `Template` 对象必须提供具有以下签名的 render()\` 方法：

#### `Template.render(context=None, request=None)`

使用给定的上下文渲染此模板。

如果提供了 `context` ，则必须是 [`dict`](https://docs.python.org/3/library/stdtypes.html#dict)。如果未提供，则引擎将使用空上下文渲染模板。

如果提供了 `request`，它必须是 [`HttpRequest`](/zh-hans/4.0/ref/request-response/#django.http.HttpRequest)。同时引擎必须使它和 CSRF 令牌在模板中可用。如何实现这一点由每个后端决定。

下面是一个搜索算法的例子。在这个例子中 [`TEMPLATES`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES) 设置为：

```python
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            '/home/html/example.com',
            '/home/html/default',
        ],
    },
    {
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [
            '/home/html/jinja2',
        ],
    },
]
```

如果你调用 `get_template('story_detail.html')`，以下是 Django 将按顺序查找的文件：

- `/home/html/example.com/story_detail.html` （`'django'` 引擎）
- `/home/html/default/story_detail.html` （`'django'` 引擎）
- `/home/html/jinja2/story_detail.html` （`'jinja2'` 引擎）

如果你调用 `select_template(['story_253_detail.html', 'story_detail.html'])`，Django 将寻找以下内容：

- `/home/html/example.com/story_253_detail.html` （`'django'` 引擎）
- `/home/html/default/story_253_detail.html` （`'django'` 引擎）
- `/home/html/jinja2/story_253_detail.html` （`'jinja2'` 引擎）
- `/home/html/example.com/story_detail.html` （`'django'` 引擎）
- `/home/html/default/story_detail.html` （`'django'` 引擎）
- `/home/html/jinja2/story_detail.html` （`'jinja2'` 引擎）

当 Django 发现一个模板存在时，它就会停止寻找。

> **提示**
>
> 你可以使用 [`select_template()`](#django.template.loader.select_template) 灵活的加载模板。例如，如果你写了一个新闻故事，并希望一些故事有自定义模板，使用类似 `select_template(['story_%s_detail.html' % story.id, 'story_detail.html'])` 。这将允许你为单个故事使用自定义模板，为没有自定义模板的故事使用备用模板。

可以——而且最好是——在每个包含模板的目录内的子目录中组织模板。惯例是为每个 Django 应用程序创建一个子目录，根据需要在这些子目录中包含子目录。

这样做是为了你自己的理智。将所有模板存储在一个目录的根级别会很麻烦。

要加载子目录中的模板，请使用斜杠，如下所示：

```python
get_template('news/story_detail.html')
```

使用与上述相同的 [`TEMPLATES`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES) 选项，这将尝试加载以下模板：

- `/home/html/example.com/news/story_detail.html` （`'django'` 引擎）
- `/home/html/default/news/story_detail.html` （`'django'` 引擎）
- `/home/html/jinja2/news/story_detail.html` （`'jinja2'` 引擎）

此外，为了减少加载和渲染模板的重复性，Django 提供了一个自动处理的快捷函数。

#### `render_to_string(template_name, context=None, request=None, using=None)`

`render_to_string()` 加载一个模板 [`get_template()`](#django.template.loader.get_template) ，并立即调用它的 `render()` 方法。它需要下面的参数。

**`template_name`**

  加载和呈现模板的名称。如果是模板名称列表，Django 使用 [`select_template()`](#django.template.loader.select_template) ，而不是 [`get_template()`](#django.template.loader.get_template) 找到模板。

**`context`**

   [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) 用作模板的渲染上下文。

**`request`**

   可选项 [`HttpRequest`](/zh-hans/4.0/ref/request-response/#django.http.HttpRequest) 在模板的渲染过程中可用。

**`using`**

  可选的模板引擎 [`NAME`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-NAME)。对模板的搜索将限于该引擎。

使用实例：

```python
from django.template.loader import render_to_string
rendered = render_to_string('my_template.html', {'foo': 'bar'})
```

还可以参看 [`render()`](/zh-hans/4.0/topics/http/shortcuts/#django.shortcuts.render) 快捷函数，它调用 [`render_to_string()`](#django.template.loader.render_to_string) ，并将结果提供给 [`HttpResponse`](/zh-hans/4.0/ref/request-response/#django.http.HttpResponse) ，适合从视图返回。

最后，您可以直接使用配置好的引擎：

#### `engines`

模板引擎可在 `django.template.engines` 中使用：

```python
from django.template import engines

django_engine = engines['django']
template = django_engine.from_string("Hello {{ name }}!")
```

在这个例子中，查找关键字“django”是引擎的 [`NAME`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-NAME)。

### 内置后端

#### `class DjangoTemplates`

设置 [`BACKEND`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-BACKEND) 为 `'django.template.backends.django.DjangoTemplates'`，以配置 Django 模板引擎。

当 [`APP_DIRS`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-APP_DIRS) 为 `True` 时，`DjangoTemplates` 引擎会在已安装应用程序的 `templates` 子目录中寻找模板。这个通用名称是为了向后兼容而保留的。

`DjangoTemplates` 引擎接受以下 [`OPTIONS`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-OPTIONS):

- `'autoescape'`：一个布尔值，控制是否启用 HTML 自动转义。

  默认为 `True`。

  > **Warning**
  >
  > 只有当你渲染非 HTML 模板时，才将其设置为 `False`！
- `'context_processors'`：当模板被请求渲染时，用于填充上下文的可调用项的点分隔 Python 路径列表。这些可调用的对象以一个请求对象作为参数，并返回一个 [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) 的项目，这些项目将被合并到上下文中。

  默认为空列表。

  查看 [`RequestContext`](/zh-hans/4.0/ref/templates/api/#django.template.RequestContext) 获取更多信息。
- `'debug'`：开启／关闭模板调试模式的布尔值。如果是 `True`，错误页面将显示模板渲染过程中出现的任何异常的详细报告。该报告包含模板的相关片段，并突出显示相应的行。

  默认为 [`DEBUG`](/zh-hans/4.0/ref/settings/#std-setting-DEBUG) 配置的值。
- `'loaders'`：模板加载器类的点分隔 Python 路径列表。每个 `Loader` 类都知道如何从特定源导入模板。可以选择使用元组来代替字符串。元组中的第一项应该是 `Loader` 类名，随后的项在初始化期间传递给 `Loader`。

  默认值取决于 [`DIRS`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-DIRS) 和 [`APP_DIRS`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-APP_DIRS) 的值。

  查看 [加载器类型](/zh-hans/4.0/ref/templates/api/#template-loaders) 获取详细信息。
- `'string_if_invalid'`：模板系统对无效变量（如拼写错误）应将此字符串输出。

  默认为空字符串。

  查看 [如何处理无效变量](/zh-hans/4.0/ref/templates/api/#invalid-template-variables) 获取更多信息。
- `'file_charset'`：用于读取磁盘上模板文件的字符集。

  默认为 `'utf-8'`。
- `'libraries'`：模板标签模块的标签字典和点分隔 Python 路径，用于向模板引擎注册。 这可用于添加新库或为现有库提供替代标签。例如：

  ```python
  OPTIONS={
      'libraries': {
          'myapp_tags': 'path.to.myapp.tags',
          'admin.urls': 'django.contrib.admin.templatetags.admin_urls',
      },
  }
  ```

  可以通过将相应的字典键传递到 [`{% load %}`](/zh-hans/4.0/ref/templates/builtins/#std-templatetag-load) 标签来加载库。
- `'builtins'`：要添加的 [内置模板标签和过滤器](/zh-hans/4.0/ref/templates/builtins/) 的点分隔 Python 路径列表。例如：

  ```python
  OPTIONS={
      'builtins': ['myapp.builtins'],
  }
  ```

  可以使用内置库中的标签和过滤器，而不需要先调用 [`{% load %}`](/zh-hans/4.0/ref/templates/builtins/#std-templatetag-load) 标签。

#### `class Jinja2`

需要安装 [Jinja2](https://jinja.palletsprojects.com/)：

```console
$ python -m pip install Jinja2
```

*Windows*

```doscon
...\> py -m pip install Jinja2
```

设置 [`BACKEND`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-BACKEND) 为 `'django.template.backends.jinja2.Jinja2'` 以配置一个 [Jinja2](https://jinja.palletsprojects.com/) 引擎。

当 [`APP_DIRS`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-APP_DIRS) 为 `True` 时，`Jinja2` 引擎会在安装的应用程序的 `jinja2` 子目录中查找模板。

[`OPTIONS`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-OPTIONS) 中最重要的条目是 `'environment'`。它是一个点分隔 Python 路径，指向一个返回 Jinja2 环境的可调用对象。默认为 `'jinja2.Environment'`。Django 调用该可调用对象并传递其他选项作为关键字参数。此外，Django 为一些选项添加了不同于 Jinja2 的默认值。

- `'autoescape'`：`True`
- `'loader'`：为 [`DIRS`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-DIRS) 和 [`APP_DIRS`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-APP_DIRS) 配置的加载器
- `'auto_reload'`：`settings.DEBUG`
- `'undefined'`：`DebugUndefined if settings.DEBUG else Undefined`

`Jinja2` 引擎也接受以下 [`OPTIONS`](/zh-hans/4.0/ref/settings/#std-setting-TEMPLATES-OPTIONS)：

- `'context_processors'`：当模板被请求渲染时，用于填充上下文的可调用项的点分隔 Python 路径列表。这些可调用的对象以一个请求对象作为参数，并返回一个 [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) 的项目，这些项目将被合并到上下文中。

  默认为空列表。

  > **不建议将上下文处理器与 Jinja2 模板一起使用。**
  >
  > 上下文处理器在 Django 模板中很有用，因为 Django 模板不支持调用带参数的函数。由于 Jinja2 没有此限制，因此建议将你要用作上下文处理器的函数放在模板的全局变量 `jinja2.Environment` 中使用，如下所述。然后你可以在模板中调用该函数。
  >
  > ```jinja
  > {{ function(request) }}
  > ```
  >
  > 有些 Django 模板的上下文处理器会返回一个固定的值。对于 Jinja2 模板，不需要这一层间接操作，因为您可以直接在 `jinja2.Environment` 中添加常量。
  >
  > 最初为 Jinja2 增加上下文处理器的用例涉及：
  >
  > - 根据请求进行昂贵的计算。
  > - 在每个模板中都需要结果。
  > - 在每个模板中多次使用结果。
  >
  > 除非满足所有这些条件，否则将函数传递给模板更符合 Jinja2 的设计。

默认配置被有意地保持为最低。如果一个模板被请求渲染（例如，当使用 [`render()`](/zh-hans/4.0/topics/http/shortcuts/#django.shortcuts.render)），`Jinja2` 后端会在上下文中添加 `request`，`csrf_input` 和 `csrf_token`。除此之外，此后端不会创建 Django 风格的环境。 它不知道 Django 过滤器和标签。 为了使用 Django 特有的 API，你必须将它们配置到环境中。

例如，您可以使用以下内容创建 `myproject/jinja2.py` ：

```python
from django.templatetags.static import static
from django.urls import reverse

from jinja2 import Environment

def environment(**options):
    env = Environment(**options)
    env.globals.update({
        'static': static,
        'url': reverse,
    })
    return env
```

并将 `'environment'` 选项设置为 `'myproject.jinja2.environment'`。

这样你就可以在 Jinja2 模板中使用以下构造：

```html+jinja
<img src="{{ static('path/to/company-logo.png') }}" alt="Company Logo">

<a href="{{ url('admin:index') }}">Administration</a>
```

Django 模板语言和 Jinja2 中都存在标签和过滤器的概念，但使用方式不同。由于 Jinja2 支持在模板中向可调用对象传递参数，所以很多在 Django 模板中需要模板标签或过滤器的功能都可以通过在 Jinja2 模板中调用函数来实现，如上例所示。Jinja2 的全局命名空间消除了对模板上下文处理器的需求。Django 模板语言并没有与 Jinja2 测试相对应的功能。
