如何覆盖模板

在您的项目中,您可能希望重写另一个Django应用程序中的模板,无论是第三方应用程序还是Contrib应用程序,例如 django.contrib.admin . 您可以将模板重写放在项目的模板目录或应用程序的模板目录中。

如果应用程序和项目模板目录都包含覆盖,则默认的django模板加载器将首先尝试从项目级目录加载模板。换言之, DIRS 以前搜索过 APP_DIRS .

参见

覆盖内置小部件模板 如果你想这么做的话。

从项目的模板目录重写

首先,我们将通过在项目的模板目录中创建替换模板来探索覆盖模板。

假设您正在尝试重写名为 blog ,提供模板 blog/post.htmlblog/list.html . 项目的相关设置如下:

from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

INSTALLED_APPS = [
    ...,
    "blog",
    ...,
]

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [BASE_DIR / "templates"],
        "APP_DIRS": True,
        # ...
    },
]

这个 TEMPLATES 设置和 BASE_DIR 如果使用默认项目模板创建了项目,则将已经存在。需要修改的设置是 DIRS .

这些设置假定您 templates 项目根目录中的目录。覆盖的模板 blog 应用程序,在 templates 目录,并将模板文件添加到该文件夹:

templates/
    blog/
        list.html
        post.html

模板加载器首先在 DIRS 目录。当视图在 blog 应用程序请求 blog/post.htmlblog/list.html 模板,加载程序将返回刚刚创建的文件。

从应用程序的模板目录重写

由于您要覆盖位于某个项目应用程序外部的模板,因此使用第一个方法并将模板覆盖放在项目的模板文件夹中更为常见。但是,如果您愿意,也可以将覆盖放在应用程序的模板目录中。

首先,确保模板设置正在应用程序目录内检查::

TEMPLATES = [
    {
        # ...
        "APP_DIRS": True,
        # ...
    },
]

如果要在名为 myapp 要覆盖的模板命名为 blog/list.htmlblog/post.html ,则目录结构如下:

myapp/
    templates/
        blog/
            list.html
            post.html

APP_DIRS 设置为 True 模板加载器将在应用程序的模板目录中查找模板。

扩展重写的模板

配置好模板加载器后,可以使用 {{% extends %}} 同时重写模板标记。这允许您进行小的定制,而不需要重新实现整个模板。

例如,可以使用此技术将自定义徽标添加到 admin/base_site.html 模板:

templates/admin/base_site.html
 {% extends "admin/base_site.html" %}

 {% block branding %}
     <img src="link/to/logo.png" alt="logo">
     {{ block.super }}
 {% endblock %}

注意的要点:

  • 该示例在 templates/admin/base_site.html 配置的项目使用 templates 要重写的目录 admin/base_site.html .

  • 新模板将扩展 admin/base_site.html ,它与被重写的模板相同。

  • 模板只替换 branding 块,添加自定义徽标,并使用 block.super 保留先前的内容。

  • 模板的其余部分继承自 admin/base_site.html .

这种技术之所以有效,是因为模板加载器不考虑已经加载的覆盖模板(在 templates/admin/base_site.html )当解决 extends 标签。与 block.super 这是一种强大的技术,可以进行小的定制。