Django: указание базового шаблона по каталогу
Я работаю над сайтом Django, который имеет несколько разделов и подразделов. Я хотел бы иметь несколько глубин наследования шаблонов: базовый шаблон для всего сайта, один базовый шаблон для каждого раздела, который наследуется от базового шаблона корня и т.д. Вот упрощенная версия моей желаемой структуры каталогов:
base.html
section1/
base.html
section2/
base.html
section3/
base.html
Я бы хотел, чтобы все файлы под section1/
содержали что-то вроде {% extends "base.html" %}
, то есть они расширяли бы section1/base.html
. section1/base.html
будет содержать что-то вроде {% extends "../base.html" %}
, что означает, что он расширит базовый файл корневого уровня. Тем не менее, я не мог найти ничего в документации, предполагая, что это возможно, и я не мог заставить Django различать "../base.html"
и "base.html"
. ({% extends "../base.html" %}
выдает ошибку.) Я полагаю, что одним из способов было бы переименование всех базовых файлов base_SECTIONNAME.html
и обновление всех файлов, которые наследуются от них, но я обеспокоен тем, что это может стать трудно поддерживать, поскольку мой сайт станет больше и разделы меняют имена и т.д. Я бы предпочел решение, которое использует естественную иерархию, заданную каталогами и подкаталогами.
Любые идеи?
Ответы
Ответ 1
Может быть, я что-то наблюдаю, но все, что вы хотите, может быть выполнено с помощью системы шаблонов django. Все расширения вызовов относятся к каталогам шаблонов.
-
Чтобы все файлы base.html в подкаталогах расширяли base.html, вам просто нужно поместить {% extends "base.html" %}
в файлы. section1/base.html будет выглядеть так.
{% extends "base.html" %}
{# ... rest of your code ...#}
-
Теперь, чтобы получить файлы из секции 1 для расширения section1/base.html, вам нужно просто положить {% extends "section1/base.html" %}
в начало. То же самое для section2, section3 и т.д.
Это просто так просто, но может быть не совсем очевидно в документации.
Надеюсь, я понял ваш вопрос.
Ответ 2
Принятый ответ будет работать, но я рекомендую использовать имена переменных, чтобы отслеживать структуру разделов. Мое личное предпочтение было бы контекстным процессором. Если, например, ваша организация раздела сайта прозрачно отражена в URL-адресе, попробуйте что-то вроде:
# It may be convenient to make this function live in or near your url conf.
def convert_url_path_to_folder_path(path):
# fill in the magic here
def sub_folder_available(request):
folder = convert_url_path_to_folder_path(request.path)
return {'subsection': folder, 'local_base':folder+'/base.html'}
Затем в вашем шаблоне просто позвоните
{% extends local_base %}
Есть, вероятно, еще десяток других способов сделать это, но главное - подумать об исключении жесткого кодирования имени папки в шаблон. Это даст вам много пробега, тем более, что вы можете просто перетащить шаблон между разделами, если они будут достаточно похожи. Еще одна вещь, которую вы можете добавить вставить:
def sub_folder_available(request):
folder = convert_url_path_to_folder_path(request.path)
# Check if local base exists:
if os.access(folder+'/base.html',os.F_OK):
base = folder+'/base.html'
else:
# revert to your global base
base = 'base.html'
return {'subsection': folder, 'base':base}
Хорошим преимуществом этой стратегии является, конечно, то, что вы можете получить раздел мух-веса и работать без какого-либо локального базового шаблона.
Ответ 3
Вы можете использовать эту библиотеку: https://github.com/vb64/django.templates.relative.path
Просто напишите в своих шаблонах следующим образом:
{% load relative_path%}
{% extends ".base.html" %}
это расширит шаблон "base.html", расположенный в той же папке, где размещен ваш шаблон
{% load relative_path%}
{% extends "... base.html" %}
расширьте шаблон "base.html", расположенный на двух уровнях выше
то же самое работает с тегом include.