覆盖模板 — Django 文档

来自菜鸟教程
Django/docs/3.1.x/howto/overriding-templates
跳转至:导航、​搜索

覆盖模板

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

如果您的应用程序和项目模板目录都包含覆盖,默认的 Django 模板加载器将首先尝试从项目级目录加载模板。 换句话说, :setting:`目录 ` 之前被搜索过 :设置:`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,
        ...
    },
]

如果您使用默认项目模板创建项目,则 :setting:`TEMPLATES` 设置和 BASE_DIR 将已经存在。 需要修改的设置是 :setting:`目录 ` .

这些设置假定您在项目的根目录中有一个 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 ,模板加载器将在应用程序的模板目录中查找并找到模板。


扩展被覆盖的模板

配置模板加载器后,您可以使用 :ttag:`{% 扩展 %} ` 模板标签,同时覆盖它。 这可以让您进行小的自定义,而无需重新实现整个模板。

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

模板/管理员/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 不变地继承。

此技术有效,因为模板加载器在解析 extends 标记时不考虑已加载的覆盖模板(在 templates/admin/base_site.html 处)。 与 block.super 结合使用是一种进行小型定制的强大技术。