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

发布于 2024-07-25 04:06:25 字数 1323 浏览 6 评论 0原文

我想在导航菜单中突出显示当前页面。 显然,当您在菜单链接的页面上时,我需要为菜单链接提供一个类似“活动”的类。 这是一个经典问题,我已经看到了许多提出的解决方案。 我的问题是我讨厌他们所有人,并且认为他们都不是很干。 例如:

@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 站点中必须存在的功能而言。 我希望默认情况下包含该请求,并且能够选择抑制它。 我找不到在中间件中执行此操作的方法,因为我无法在视图返回模板后渲染模板之前拦截模板。

有什么建议么?

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:

@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.

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:

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.

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沉鱼一梦 2024-08-01 04:06:26

为了将来参考,可以使用 django-tabs 来完成 OP 想要的操作。

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

﹎☆浅夏丿初晴 2024-08-01 04:06:25

您的意图是有道理的,大多数时候您都需要 RequestContext ,并且只有极少数情况下才可以出于性能原因安全地省略它。 解决方案很简单,使用 direct_to_template 快捷方式代替 render_to_response

from django.views.generic.simple import direct_to_template

def contact(request):
    # snip ...
    return direct_to_template(request, 'contact.html', { 'myvar' : myvar })

... 或 django-annoying

from annoying.decorators import render_to

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

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:

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:

from annoying.decorators import render_to

@render_to('template.html')
def foo(request):          
    bar = Bar.object.all()  
    return {'bar': bar}     
寒尘 2024-08-01 04:06:25

您不必对导航标记执行任何操作即可为当前导航标记提供不同的样式 - 有使用 CSS 的声明性方法来执行此操作。

在这里查看我的答案:Django:是否有更好的方法将当前页面链接加粗作为示例。

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.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文