С какой стати я должен передавать RequestContext во всех моих ответах?

Я хочу выделить текущую страницу в меню навигации. Очевидно, что я должен дать ссылкам меню класс, подобный "активный", когда вы находитесь на их странице. Это классическая проблема, и я видел много предложенных решений. Моя проблема в том, что я ненавижу их всех и считаю, что ни один из них не очень СУХОЙ. Например:

@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 и возвращает "активный", если вы находитесь на этой странице. В качестве альтернативы это можно сделать с помощью именованных представлений, а не URL-адресов, но принцип тот же.

Моя главная проблема с этим заключается в том, что моя навигация будет вызываться на 99% моих просмотров, и все же, чтобы получить текущую переменную запроса, я все еще должен проанализировать RequestContext к шаблону с чем-то вроде этого:

def contact(request):
    # snip ...
    return render_to_response(
                'contact.html',
                { 'myvar' : myvar },
                context_instance=RequestContext(request))

Почему мне нужно добавить эту строку context_instance для каждого из моих представлений, когда, вероятно, всем, кроме одного, нужна переменная запроса, чтобы получить текущий URL / представление для выделения активной ссылки? Это кажется ужасно мокрым, особенно для функции, которая должна присутствовать в большинстве сайтов django. Я хочу, чтобы запрос был включен по умолчанию и мог по желанию подавить его. Я не могу найти способ сделать это в промежуточном программном обеспечении, так как не могу перехватить шаблон до его визуализации после того, как представление вернуло его.

Какие-либо предложения?

3 ответа

Решение

Ваше намерение имеет смысл, вам нужно 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 декоратор от django-раздражает:

from annoying.decorators import render_to

@render_to('template.html')
def foo(request):          
    bar = Bar.object.all()  
    return {'bar': bar}     

Вам не обязательно делать что-либо с разметкой вашей навигации, чтобы придать текущей разный стиль - существуют декларативные способы сделать это с помощью CSS.

Смотрите мой ответ здесь: Django: Есть ли лучший способ выделить ссылку на текущую страницу для примера.

Для дальнейшего использования можно использовать вкладки django для выполнения желаемого OP.

Другие вопросы по тегам