在Django站点上,如何显示正确的节导航



我正在重新设计一个Django站点,它被分成几个部分。每个部分都有一组单独的导航。我在纠结如何最好地突出正确的那个。

最初,我开始在视图中设置上下文变量,并使用它来选择正确的子导航。如:

# views.py
class HomeView(TemplateView):
    template_name = 'home.html'
    def get_context_data(self, **kwargs):
        context = super(HomeView, self).get_context_data(**kwargs)
        context['subnav'] = 'news'
        return context
# templates/base.html
{% if subnav %}
    <ul>
        {% if subnav == 'news' %}
            <li><a href="#">Link 1</a></li>
            <li><a href="#">Link 2</a></li>
        {% elif subnav == 'sport' %}
            <!-- etc -->
        {% endif %}
    </ul>
{% endif %}

那很好…但前提是每个页面都有视图。例如,所有的flatpage都没有。

我在上下文处理器和模板标签上转了一圈又一圈,似乎没有什么令人满意的。什么好主意吗?

(一种明显的方法是将每个子导航HTML放在单独的模板中,并从这些模板扩展到单独的页面…但是我已经在不同类型的布局中使用了模板继承,并且添加section的维度会使事情变得非常复杂。

我已经想出了一个看似合理的解决方案。

我做了一个自定义的赋值标签,它为当前页面设置子导航的名称:

# templatetags/nav_tags.py
from django import template
register = template.Library()
@register.assignment_tag
def get_subnav(request):
    # The names on the right are the names of URLs:
    subnavs = (
        ('news', ('home', 'news_archive', 'news_month_archive')),
        ('sport', ('sport_home', 'sport_archive', 'sport_month_archive')),
        # etc
    )
    url_name = request.resolver_match.url_name
    for subnav, names in subnavs:
        if url_name in names:
            return subnav
    return False

指出:

  • 这假设你在urls.py中使用命名url。
  • request.resolver_match.url_name仅在Django 1.5之后可用。

然后在模板中我可以做:

{% load nav_tags %}
{% get_subnav request as subnav %}
{% if subnav %}
    <ul>
        {% if subnav == 'news' %}
            <li><a href="#">Link 1</a></li>
            <li><a href="#">Link 2</a></li>
        {% elif subnav == 'sport' %}
            <!-- etc -->
        {% endif %}
    </ul>
{% endif %}

这样做的好处是减少了"if"请求的数量。路径=这个或请求。Path =那个或者request.path=…"不依赖于任何地方的实际URL路径的好处,这对我来说总是很脆弱——这就是命名URL的作用。

我还制作了一个上下文处理器,将url_name放在模板上下文中,因为我发现它对周围有用,并阻止我依赖于其他地方的URL路径。

最新更新