テンプレートをオーバーライドする

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

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

参考

そのようなことをしたい場合は、組み込みのウィジェットテンプレートをオーバーライドする を読んでください。

プロジェクトのtemplatesディレクトリからオーバーライドする

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

blog/post.htmlblog/list.html というテンプレートを提供している blog というサードパーティアプリケーションのテンプレートをオーバーライドしようとしているとしましょう。プロジェクトに関連する設定は次のようになります:

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_DIRSTrue に設定すると、テンプレートローダーはアプリのテンプレートディレクトリを探し、テンプレートを見つけることができます。

オーバーライドされたテンプレートを継承(extend)する

テンプレートローダーが設定されていれば、 {% 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 にファイルを作成し、 admin/base_site.html を上書きするために、設定されたプロジェクトレベルの templates ディレクトリを使用します。
  • 新しいテンプレートは admin/base_site.html を継承しており、これはオーバーライドされるテンプレートと同じです。
  • このテンプレートは branding ブロックだけを置き換え、カスタムロゴを追加し、 block.super を使って以前のコンテンツを保持します。
  • 残りのテンプレートは admin/base_site.html からそのまま継承されます。

このテクニックは、テンプレートローダーが extends タグを解決するときに、すでにロードされているオーバーライドテンプレート (templates/admin/base_site.html) を考慮しないので動作します。 block.super と組み合わせることで、小さなカスタマイズを行うための強力なテクニックとなります。

Back to Top