How to override templates

プロジェクトでは、django.contrib.admin のような contrib アプリケーションやサードパーティアプリケーションで Djangoアプリケーションのテンプレートを上書きすることができます。 テンプレートの上書きは、プロジェクトのテンプレートディレクトリまたはアプリケーションのテンプレートディレクトリに置くことができます。

オーバーライドが含まれている app と project の両方のテンプレートディレクトリがある場合、デフォルトの Django テンプレートローダは、まずプロジェクトレベルのディレクトリからテンプレートをロードしようとします。つまり、 DIRSAPP_DIRS より前に検索されます。

参考

そのようなことをしたい場合は、Overriding built-in widget templates を読んでください。

Overriding from the project's templates directory

最初に、プロジェクトのテンプレートディレクトリに置き換え用テンプレートを作成して、テンプレートのオーバーライドを検討します。

Let's say you're trying to override the templates for a third-party application called blog, which provides the templates blog/post.html and blog/list.html. The relevant settings for your project would look like:

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,
        ...
    },
]

The TEMPLATES setting and BASE_DIR will already exist if you created your project using the default project template. The setting that needs to be modified is DIRS.

These settings assume you have a templates directory in the root of your project. To override the templates for the blog app, create a folder in the templates directory, and add the template files to that folder:

templates/
    blog/
        list.html
        post.html

The template loader first looks for templates in the DIRS directory. When the views in the blog app ask for the blog/post.html and blog/list.html templates, the loader will return the files you just created.

Overriding from an app's template directory

Since you're overriding templates located outside of one of your project's apps, it's more common to use the first method and put template overrides in a project's templates folder. If you prefer, however, it's also possible to put the overrides in an app's template directory.

First, make sure your template settings are checking inside app directories:

TEMPLATES = [
    {
        ...,
        'APP_DIRS': True,
        ...
    },
]

If you want to put the template overrides in an app called myapp and the templates to override are named blog/list.html and blog/post.html, then your directory structure will look like:

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

With APP_DIRS set to True, the template loader will look in the app's templates directory and find the templates.

Extending an overridden template

With your template loaders configured, you can extend a template using the {% extends %} template tag whilst at the same time overriding it. This can allow you to make small customizations without needing to reimplement the entire template.

For example, you can use this technique to add a custom logo to the admin/base_site.html template:

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

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

Key points to note:

  • The example creates a file at templates/admin/base_site.html that uses the configured project-level templates directory to override admin/base_site.html.
  • The new template extends admin/base_site.html, which is the same template as is being overridden.
  • The template replaces just the branding block, adding a custom logo, and using block.super to retain the prior content.
  • The rest of the template is inherited unchanged from admin/base_site.html.

This technique works because the template loader does not consider the already loaded override template (at templates/admin/base_site.html) when resolving the extends tag. Combined with block.super it is a powerful technique to make small customizations.