Django: Как я могу определить вызывающий вид из шаблона?
Краткая версия:
Есть ли простой, встроенный способ идентификации вызывающего представления в шаблоне Django, без передачи дополнительных контекстных переменных?
Длинная (оригинальная) версия:
В одном из моих приложений Django есть несколько разных представлений, каждый со своим собственным шаблоном URL-адреса, который отображает один и тот же шаблон. Там очень небольшое количество кода шаблона, которое нужно изменить в зависимости от вызываемого представления, слишком мало, чтобы стоить накладных расходов на настройку отдельных шаблонов для каждого вида, поэтому в идеале мне нужно найти способ идентификации вызывающего представления в шаблоне.
Я попытался настроить представления для передачи дополнительных контекстных переменных (например, "имя_выпуска" ), чтобы идентифицировать вызывающее представление, и я также попытался использовать сравнения {% ifequal request.path "/some/path/" %}
, но ни одно из этих решений не кажется особенно элегантным. Есть ли лучший способ идентифицировать вызывающий вид из шаблона? Есть ли способ доступа к имени представления или имени шаблона URL?
Обновление 1: Что касается комментария, это просто случай, когда я недопонимаю MVC, я понимаю MVC, но Django на самом деле структура MVC. Я считаю, что способ, которым настроено мое приложение, согласуется с тем, что Django использует MVC: представления описывают, какие данные представлены, и шаблоны описывают, как данные представлены. Просто случается, что у меня есть несколько представлений, которые готовят разные данные, но все используют один и тот же шаблон, потому что данные представлены одинаково для всех представлений. Я просто ищу простой способ идентифицировать вызывающий вид из шаблона, если он существует.
Обновление 2: Спасибо за все ответы. Я думаю, что вопрос передумал - как уже упоминалось в моем первоначальном вопросе, я уже рассмотрел и пробовал все предлагаемые решения, поэтому я перегнал его до "короткой версии" в верхней части вопроса, И прямо сейчас кажется, что если бы кто-то просто поставил "Нет", это был бы самый правильный ответ:)
Обновление 3: Карл Мейер опубликовал "Нет":) Еще раз спасибо.
Ответы
Ответ 1
Нет, и это была бы плохая идея. Для прямого обращения к имени функции вида из шаблона вводится слишком плотная связь между слоем представления и уровнем шаблона.
Намного лучшим решением здесь является система наследования шаблонов Django. Определите общий родительский шаблон с блоком для (небольшой) области, который необходимо изменить в каждой версии просмотра. Затем определите каждый шаблон представления, чтобы перейти от родителя и соответствующим образом определить этот блок.
Ответ 2
Так как Django 1.5, url_name
доступен с помощью:
request.resolver_match.url_name
До этого вы можете использовать для этого промежуточное ПО:
from django.core.urlresolvers import resolve
class ViewNameMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
url_name = resolve(request.path).url_name
request.url_name = url_name
Затем добавив это в MIDDLEWARE_CLASSES, и в шаблонах у меня есть следующее:
{% if request.url_name == "url_name" %} ... {% endif %}
рассмотрение RequestContext (запрос) всегда передается функции рендеринга. Я предпочитаю использовать url_name для URL-адресов, но можно использовать имя метода(). App_name и resolve(). Func.name, но это не работает с декораторами - вместо этого возвращается имя функции декоратора.
Ответ 3
Это звучит как прекрасный пример общего представления, которое вы можете настроить.
Смотрите следующие ресурсы:
Эти ссылки должны помочь вам упростить ваши взгляды и ваши шаблоны соответственно.
Ответ 4
Я работаю над этим для системы справочной страницы, где мне нужно, чтобы каждое представление соответствовало странице справки в моих cms с показанной по умолчанию страницей, если для этого представления не была указана страница справки. Я наткнулся на в этом блоге, где они используют обработчик контекста шаблона, а некоторые python проверяют магию, чтобы вывести имя представления и заполнить контекст с ним.
Ответ 5
С Django 1.5 вы можете получить доступ к экземпляру ResolverMatch через request.resolver_match.
ResolverMatch предоставляет вам разрешенное имя, пространство имен и т.д.
Ответ 6
одно простое решение:
def view1(req):
viewname = "view1"
and pass this viewname to the template context
def view2(req):
viewname = "view2"
and pass this viewname to the template context
в шаблоне обращаться к имени представления как
{{viewname}}
а также вы можете использовать это в сравнении.
Ответ 7
Большинство общих представлений - если не все - наследует ContextMixin
, который добавляет переменную контекста view
, которая указывает на экземпляр View.
Ответ 8
Почему бы не попробовать настроить cookie сеанса, а затем прочитать cookie из вашего шаблона.
в ваших представлениях выберите файлы cookie
def view1(request):
...
#set cookie
request.session["param"]="view1"
def view2(request):
request.session["param"]="view2"
then in your ONE template check something like..
{% ifequal request.session.param "view1" %}
... do stuff related to view1
{% endifequal %}
{% ifequal request.session.param "view2" %}
... do stuff related to "view2"
{% endifequal %}
Гаф