添加"有效"在Django的基于类的视图中导航类到导航栏

时间:2015-04-08 02:07:08

标签: django

在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/...处的页面旁边应该有class="active"""导航栏HTML中的项目。 DRYest这样做的方法是什么?

我想避免将CBV子类化,只是为了将请求添加到模板上下文(标准模板标签解决方案似乎需要)。目前我们以愚蠢的方式执行此操作:为每个导航栏项标记添加{% block %},并在每个模板中将相关块设置为class="active"。似乎是浪费。

3 个答案:

答案 0 :(得分:2)

您可以使用此代码段将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>

答案 1 :(得分: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',
        ],
    },
},

此外,就像对视图的非常普遍的看法一样,你应该保持视图逻辑 在视图中,如果您需要构建一些mixin,那就是这样。保持网址小。

答案 2 :(得分:0)

如果我理解正确的话,我就有了问题,我使用jQuery这样解决了这个问题:

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

function getCurrentUrlPath() {
    return location.pathname;
}