Django: переопределение и расширение шаблона приложения

Если вы хотите переопределить шаблон, поставляемый с приложением в django (в приложении /templates/app/ ), вы создаете шаблон с тем же именем в другом каталоге, который загрузчик шаблонов проверяет перед каталогом шаблона приложения. Если вы просто хотите переопределить определенные блоки шаблона, вам также нужно скопировать все изменения в блоке шаблона, которые на самом деле не очень сухие.

Кто-нибудь знает способ переопределить шаблон orginial, в то же время расширяя его, так что вам просто нужно переопределить конкретный блок, который вы хотите изменить? (это делается без изменения имени шаблона, поскольку в некоторых случаях вам может потребоваться изменить представление, чтобы заставить его работать с другим шаблоном)

EDIT: Как заметил Адам Тейлор в комментариях Django 1.9 на, это возможно без каких-либо хаков.

Ответ 1

Я думаю, что ответ из этого связанного вопроса уместен; в настоящее время лучшим решением является использование пользовательского загрузчика шаблонов из пакета django-apptemplates на PyPI, поэтому вы можете просто использовать pip, чтобы установить его (например, pip install django-apptemplates).

Загрузчик шаблонов позволяет вам расширить шаблон в определенном приложении; например, чтобы расширить страницу индекса админ-интерфейса, добавьте

'apptemplates.Loader',

в список TEMPLATE_LOADERS в settings.py и используйте

{% extends "admin:admin/index.html" %}

в ваших шаблонах.

Ответ 2

Как обновление, поскольку это, кажется, популярный вопрос. Я использовал перенаправить приложение без каких-либо проблем. Он предоставляет новые ключевые слова overextends, что позволяет расширять шаблоны с тем же именем.

И легко установить с помощью pip:

 pip install -U django-overextends

Ответ 3

Django 1.9 и более поздние версии эту функцию:

Загрузчики шаблонов Django теперь могут рекурсивно расширять шаблоны.

Таким образом, у вас может быть файл из app1 с таким содержимым:

app1/templates/example/foobar.html:

<p>I'm from app1</p>
{% block main %}{% endblock %}

И вы можете расширить его с помощью файла из app2 (обратите внимание, что имя шаблона example/foobar.html совпадает):

app2/templates/example/foobar.html:

{% extends "example/foobar.html" %}
{% block main %}
  <p>I'm from app2</p>
{% endblock %}

Конечный результат должен быть:

<p>I'm from app1</p>
<p>I'm from app2</p>

Ответ 4

В вики Django Саймон Уиллисон представляет трюк для достижения эффекта "саморасширяющегося шаблона". Это не применимо напрямую, если вы используете загрузчик шаблонов app_directories.

Ссылки на шаблоны шаблонов приложений в новом каталоге могут сделать трюк.

Ответ 5

[обновление]

Я неправильно понял вопрос, мой первоначальный ответ применим только к приложению администратора, у которого есть встроенный механизм расширения шаблонов. Для другого приложения, которому не хватает такого механизма, я бы просто разблокировал исходные шаблоны вместо того, чтобы возиться с настраиваемыми загрузчиками шаблонов, например, с выбранным ответом. Если вы беспокоитесь о forking, вы также можете реализовать механизм расширения и внести свой вклад в исходный проект, если считаете, что это стоит.


[оригинальный ответ]

Прямо от тонкого руководства: Из-за модульной конструкции шаблонов администратора обычно не требуется и не рекомендуется заменять весь шаблон. Почти всегда лучше переопределять только часть шаблона, которую нужно изменить.

Чтобы продолжить описанный выше пример, мы хотим добавить новую ссылку рядом с инструментом "История" для модели страницы. Посмотрев на change_form.html, мы определяем, что нам нужно только переопределить блок объектных инструментов. Поэтому вот наш новый change_form.html:

{% extends "admin/change_form.html" %}
{% load i18n %}
{% block object-tools %}
{% if change %}{% if not is_popup %}
  <ul class="object-tools">
    <li><a href="history/" class="historylink">{% trans "History" %}</a></li>
    <li><a href="mylink/" class="historylink">My Link</a></li>
    {% if has_absolute_url %}
        <li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink">
            {% trans "View on site" %}</a>
        </li>
    {% endif%}
  </ul>
{% endif %}{% endif %}
{% endblock %}

И это! Если мы разместим этот файл в каталоге templates/admin/my_app, наша ссылка появится в каждой форме изменения модели.

Ответ 6

Один простой способ сделать это:

Предположим, вы хотите расширить и переопределить django/contrib/admin/templates/admin/change_form.html.

Сначала скопируйте исходный файл change_form.html в каталог шаблона приложения и переименуйте его как нечто вроде myapp/templates/admin/original_change_form.html. (Вы также можете сделать это как символическую ссылку.)

Во-вторых, создайте свой собственный файл change_form.html в myapp/templates/admin. В верхней части окна введите следующее:

{% extends "admin/original_change_form.html" %}

Simple!