С какой стати я должен передавать RequestContext во всех своих ответах?
-
20-08-2019 - |
Вопрос
Я хочу выделить текущую страницу в меню навигации.Очевидно, мне нужно присвоить ссылкам на меню класс типа "active", когда вы находитесь на их странице.Это классическая проблема, и я видел много решений предлагаемый.Моя проблема в том, что я ненавижу их все и не считаю ни один из них очень СУХИМ.Например:
@register.simple_tag
def active(request, pattern):
import re
if re.search(pattern, request.path):
return 'active'
return ''
----
{% load tags %}
<div id="navigation">
<a class="{% active request "^/about/" %}" href="/about/">About</a>
<a class="{% active request "^/contact/" %}" href="/contact/">Contact</a>
<a class="{% active request "^/services/" %}" href="/services/">Services</a>
</div>
Тег принимает ваш текущий запрос и URL-выражение и возвращает 'active', если вы в данный момент находитесь на этой странице.В качестве альтернативы это можно сделать с помощью именованных представлений, а не URL-адресов, но принцип тот же.
Моя основная проблема с этим заключается в том, что моя навигация будет вызываться в 99% моих просмотров, и все же, чтобы получить текущую переменную запроса, мне все еще нужно проанализировать RequestContext для шаблона с чем-то вроде этого:
def contact(request):
# snip ...
return render_to_response(
'contact.html',
{ 'myvar' : myvar },
context_instance=RequestContext(request))
Почему мне нужно добавлять эту строку context_instance к каждому из моих представлений, когда, вероятно, все, кроме одного из них потребности переменная запроса для того, чтобы получить текущий URL / просмотр, чтобы выделить активную ссылку?Это кажется ужасно мокрым, особенно для функции, которая должна быть на подавляющем большинстве сайтов django.Я хочу, чтобы запрос был включен по умолчанию и мог при необходимости подавлять его.Я не могу найти способ сделать это в промежуточном программном обеспечении, поскольку я не могу перехватить шаблон до его рендеринга после того, как представление вернет его.
Есть какие-нибудь предложения?
Решение
Ваше намерение имеет смысл, вам понадобится RequestContext
в большинстве случаев и лишь в редких случаях его можно безопасно опустить по соображениям производительности.Решение простое, вместо render_to_response
использование direct_to_template
короткий путь:
from django.views.generic.simple import direct_to_template
def contact(request):
# snip ...
return direct_to_template(request, 'contact.html', { 'myvar' : myvar })
...или render_to
декоратор из джанго-раздражающий:
from annoying.decorators import render_to
@render_to('template.html')
def foo(request):
bar = Bar.object.all()
return {'bar': bar}
Другие советы
Вам не обязательно что-либо делать с разметкой вашей навигации, чтобы придать текущей другой стиль - существуют декларативные способы сделать это с помощью CSS.
Смотрите мой ответ здесь: Джанго:Есть ли лучший способ выделить жирным шрифтом ссылку на текущую страницу для примера.
Для дальнейшего использования можно использовать django-вкладки за то, что сделал то, что хотел ОП.