How to override templates¶
В своем проекте вы можете захотеть переопределить шаблон в другом приложении Django, будь то стороннее приложение или приложение contrib, такое как django.contrib.admin
. Вы можете поместить переопределения шаблонов либо в каталог шаблонов вашего проекта, либо в каталог шаблонов приложения.
Если у вас есть каталоги шаблонов приложений и проектов, которые оба содержат переопределения, загрузчик шаблонов Django по умолчанию будет пытаться сначала загрузить шаблон из каталога на уровне проекта. Другими словами, DIRS
будет искаться раньше, чем APP_DIRS
.
См.также
Прочитайте Переопределение встроенных шаблонов виджетов, если вы хотите это сделать.
Переопределение из каталога шаблонов проекта¶
Сначала мы изучим переопределение шаблонов путем создания заменяющих шаблонов в каталоге шаблонов вашего проекта.
Допустим, вы пытаетесь переопределить шаблоны для стороннего приложения под названием blog
, которое предоставляет шаблоны blog/post.html
и blog/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.html
и blog/list.html
, загрузчик вернет только что созданные файлы.
Переопределение из каталога шаблонов приложения¶
Поскольку вы переопределяете шаблоны, расположенные вне одного из приложений вашего проекта, чаще всего используется первый метод, и переопределения шаблонов размещаются в папке templates проекта. Однако при желании можно поместить переопределения в каталог шаблонов приложения.
Во-первых, убедитесь, что настройки шаблона проверяются в каталогах приложений:
TEMPLATES = [
{
...,
'APP_DIRS': True,
...
},
]
Если вы хотите поместить переопределения шаблонов в приложение под названием myapp
, а переопределяемые шаблоны называются blog/list.html
и blog/post.html
, то ваша структура каталогов будет выглядеть следующим образом:
myapp/
templates/
blog/
list.html
post.html
Если для APP_DIRS
установлено значение True
, загрузчик шаблонов будет искать в каталоге шаблонов приложения и находить шаблоны.
Расширение переопределенного шаблона¶
Настроив загрузчики шаблонов, вы можете расширить шаблон с помощью тега шаблона {% extends %}
и в то же время переопределить его. Это может позволить вам сделать небольшие изменения без необходимости переделывать весь шаблон.
Например, вы можете использовать эту технику для добавления пользовательского логотипа в шаблон 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
это мощная техника для выполнения небольших настроек.