Por que diabos eu tenho que passar RequestContext em todas as minhas respostas?
-
20-08-2019 - |
Pergunta
quero destacar a página atual no menu de navegação. Obviamente, eu preciso dar os links do menu uma classe como 'ativo' quando você está em sua página. Este é um problema clássico e já vi muitas soluções proposta . Meu problema é que eu odeio todos eles e considerar nenhum deles ser muito seco. Por exemplo:
@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>
A marca leva o seu pedido atual e uma expressão url e retorna 'ativa', se você está atualmente nesta página. Alternativamente, esta pode ser feito com vistas nomeadas em vez de URLs, mas o princípio é o mesmo.
A principal problema com isto é que a minha navegação serão chamados 99% dos meus pontos de vista e ainda, a fim de obter a variável atual solicitação ainda tenho parse um RequestContext para o modelo com algo como isto:
def contact(request):
# snip ...
return render_to_response(
'contact.html',
{ 'myvar' : myvar },
context_instance=RequestContext(request))
Por que eu preciso para adicionar esta linha context_instance para cada um dos meus pontos de vista, quando provavelmente todos, mas um deles necessidades a variável pedido a fim de obter a corrente url / vista para destacar a ativa ligação? Este parece muito molhado, especialmente para um recurso que deve ser na grande maioria do Django sites. Eu quero que o pedido para ser incluído por padrão e ser capaz de opcionalmente suprimi-lo. Não consigo encontrar uma maneira de fazer isso em middleware como eu não pode interceptar o modelo antes de sua prestado após a exibição voltou-lo.
Todas as sugestões?
Solução
Sua intenção faz sentido, você vai precisar RequestContext
maior parte do tempo e só raramente pode ser omitido seguramente por razões de desempenho. A solução é simples, em vez de render_to_response
atalho uso 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 })
... ou render_to
decorador de django-irritante:
from annoying.decorators import render_to
@render_to('template.html')
def foo(request):
bar = Bar.object.all()
return {'bar': bar}
Outras dicas
Você não necessariamente tem que fazer alguma coisa para a marcação de sua navegação para dar o atual um estilo diferente - existem formas declarativas de fazer isso usando CSS
.Veja a minha resposta aqui: Django: existe uma melhor maneira de negrito a corrente página da ligação para um exemplo
.Para referência futura, pode-se usar django-guias para fazer o que queria OP .