【问题标题】:Add "active" navigation class to navbar in Django's class-based views在基于 Django 类的视图中将“活动”导航类添加到导航栏
【发布时间】:2015-04-08 19:40:20
【问题描述】:

在 Django 应用程序中,很多基于类的视图都是直接从 urls.py 调用的

url(r'^manage/thing/$',
    ListView.as_view(model=Thing,
                     queryset=Thing.objects.filter(parent=None)),
    name='mg_thing_list'),

而且大多数 CBV 没有子类,所以 views.py 几乎是空的。我想根据 URL 突出显示导航栏中的活动部分。例如,/manage/thing/... 的页面应该在导航栏 HTML 中的“事物”项旁边有 class="active"。这样做的最干燥方式是什么?

我想避免仅仅为了将请求添加到模板上下文(标准模板标签解决方案似乎需要)而对 CBV 进行子类化。目前我们以一种愚蠢的方式做到这一点:为每个导航栏项目标签添加一个{% block %},并在每个模板中将相关块设置为class="active"。好像有点浪费。

【问题讨论】:

标签: django


【解决方案1】:

首先,不建议在 urls.py 中保存逻辑,这里也有两种方法可以解决您的问题

首先是一个模板上下文处理器:(在 myapp/context_processors.py 中)

def mytag(request):
     context = {'class': 'active'}
     return context

然后

<div class='{{ class }}'>

最后将模板上下文处理器添加到 settings.py 或 Django 1.8 中的 TEMPLATE_CONTEXT_PROCESSORS 中

TEMPLATES = [
{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': ['components/templates'],
    'APP_DIRS': True,
    'OPTIONS': {
        'context_processors': [
            'django.template.context_processors.debug',
            'django.template.context_processors.request',
            'django.contrib.auth.context_processors.auth',
            'django.contrib.messages.context_processors.messages',
            'myapp.context_processors.mytag',
        ],
    },
},

此外,正如对视图的一种非常普遍的看法,您应该保持视图逻辑 在视图中,如果您需要构建一些混入,您可以这样做。保持网址小。

【讨论】:

    【解决方案2】:

    您可以使用此 sn-p 将 active 类添加到您的 html 代码中。它根据 url name 参数进行反向解析。

    your_app/templatetags/base_utils.py

    from django import template
    from django.core import urlresolvers
    
    register = template.Library()    
    
    @register.simple_tag(takes_context=True)
    def current(context, url_name, return_value=' active', **kwargs):
        matches = current_url_equals(context, url_name, **kwargs)
        return return_value if matches else ''
    
    
    def current_url_equals(context, url_name, **kwargs):
        resolved = False
        try:
            resolved = urlresolvers.resolve(context.get('request').path)
        except:
            pass
        matches = resolved and resolved.url_name == url_name
        if matches and kwargs:
            for key in kwargs:
                kwarg = kwargs.get(key)
                resolved_kwarg = resolved.kwargs.get(key)
    
                if kwarg:
                    # for the comparison of same type url arg d+ w+
                    kwarg = unicode(kwarg)
    
                if not resolved_kwarg or kwarg != resolved_kwarg:
                    return False
        return matches
    

    your_template.html

    {% load base_utils %}
    <li class="{% current 'your_url_name' param1=param1 param_N=param_N %}"><a href="{% url 'your_url_name' param1=param1 param_N=param_N %}"> This is NavBar Button </a></li>
    

    【讨论】:

    • context.get('request').path 来自哪里?据我所知,在 CBV 传递给模板(Django 1.7)的上下文中没有请求键。
    • 上下文来自标签注册:@register.simple_tag(takes_context=True)
    • 是的,有上下文,但里面没有请求。
    • 这些是标签,我其实比我更喜欢他的回答。
    • 非常好,尽管如果您使用命名空间 URL,例如 myapp:index - resolved.url_name 在这种情况下是“索引”,那么比较会失败。解决方法:将resolved.url_name == url_name替换为":".join( (resolved.namespace, resolved.url_name,) ) == url_name
    【解决方案3】:

    如果我理解正确,我有这个问题,我通过使用jQuery 解决了这个问题:

    function mainNavListAddClass() {
        var theA = $("a[href=" + "'" + getCurrentUrlPath() + "'" + "]");
        if (theA.length) {
            theA.first().addClass("active");
        }
    }
    
    function getCurrentUrlPath() {
        return location.pathname;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-06
      • 1970-01-01
      相关资源
      最近更新 更多