如何覆寫範本

在您的專案中,您可能需要覆寫另一個 Django 應用程式中的範本,無論是第三方應用程式還是像是 django.contrib.admin 的 contrib 應用程式。您可以將範本覆寫放在專案的範本目錄中,或是應用程式的範本目錄中。

如果您的應用程式和專案範本目錄都包含覆寫,預設的 Django 範本載入器會先嘗試從專案層級的目錄載入範本。換句話說,會先搜尋 DIRS,然後才搜尋 APP_DIRS

另請參閱

如果您想覆寫內建的 widget 範本,請閱讀 覆寫內建 widget 範本

從專案的範本目錄覆寫

首先,我們將探討如何透過在您專案的範本目錄中建立替代範本來覆寫範本。

假設您想要覆寫一個名為 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 繼承而不變。

這項技術之所以有效,是因為範本載入器在解析 extends 標籤時,不會考慮已經載入的覆寫範本 (位於 templates/admin/base_site.html)。結合 block.super,它是一種強大的技術,可以進行小的自訂。

返回頂端