为什么我必须在所有响应中传递RequestContext?

时间:2022-05-30 07:28:00

I want to highlight the current page in the navigation menu. Obviously I need to give the menu links a class like 'active' when you are on their page. This is a classic problem and I've seen many solutions proposed. My problem is I hate all of them and consider none of them to be very DRY. For example:

我想突出显示导航菜单中的当前页面。显然,当你在他们的页面上时,我需要给菜单链接一个类似'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>

The tag takes your current request and a url expression and returns 'active' if you're currently on this page. Alternatively this can be done with named views rather than urls but the principle is the same.

标记会获取您当前的请求和网址表达式,如果您当前在此页面上,则会返回“有效”。或者,这可以使用命名视图而不是URL来完成,但原理是相同的。

My main issue with this is that my navigation will be called on 99% of my views and yet, in order to get the current request variable I still have parse a RequestContext to the template with something like this:

我的主要问题是我的导航将在99%的视图中被调用,然而,为了获得当前请求变量,我仍然使用以下内容解析RequestContext到模板:

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

Why do I need to add this context_instance line to every single one of my views when probably all but one of them needs the request variable in order to get the current url/view to highlight the active link? This seems awfully wet, especially for a feature that must be in the great majority of django sites. I want the request to be included by default and be able to optionally suppress it. I can't find a way to do this in middleware as I can't intercept the template before its rendered after the view has returned it.

为什么我需要将这个context_instance行添加到我的每个视图中,除非其中一个人可能只需要一个请求变量,以便获取当前的URL /视图以突出显示活动链接?这看起来非常潮湿,特别是对于必须在大多数django网站中的功能。我希望默认情况下包含请求,并且可以选择禁止它。我找不到在中间件中执行此操作的方法,因为在视图返回之后,我无法在模板呈现之前拦截模板。

Any suggestions?

3 个解决方案

#1


16  

Your intention makes sense, you'll need RequestContext most of the time and only rarely it can be safely omitted for performance reasons. The solution is simple, instead of render_to_response use direct_to_template shortcut:

你的意图是有道理的,你大部分时间都需要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 })

... or render_to decorator from django-annoying:

......或者来自django-annoying的render_to装饰:

from annoying.decorators import render_to

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

#2


1  

You don't necessarily have to do anything to the markup of your navigation to give the current one a different style - there are declarative ways to do that using CSS.

您不一定要对导航的标记做任何事情,以使当前的标记具有不同的样式 - 有使用CSS的声明性方法。

See my answer here: Django: Is there a better way to bold the current page link for an example.

在这里查看我的答案:Django:有没有更好的方法来加粗当前页面链接的示例。

#3


0  

For future reference, one can use django-tabs for doing what OP wanted.

为了将来参考,可以使用django-tabs来做OP想要的事情。

#1


16  

Your intention makes sense, you'll need RequestContext most of the time and only rarely it can be safely omitted for performance reasons. The solution is simple, instead of render_to_response use direct_to_template shortcut:

你的意图是有道理的,你大部分时间都需要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 })

... or render_to decorator from django-annoying:

......或者来自django-annoying的render_to装饰:

from annoying.decorators import render_to

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

#2


1  

You don't necessarily have to do anything to the markup of your navigation to give the current one a different style - there are declarative ways to do that using CSS.

您不一定要对导航的标记做任何事情,以使当前的标记具有不同的样式 - 有使用CSS的声明性方法。

See my answer here: Django: Is there a better way to bold the current page link for an example.

在这里查看我的答案:Django:有没有更好的方法来加粗当前页面链接的示例。

#3


0  

For future reference, one can use django-tabs for doing what OP wanted.

为了将来参考,可以使用django-tabs来做OP想要的事情。