在Django网站上,如何显示正确的部分导航

时间:2014-08-05 15:50:07

标签: django django-templates

我正在重新处理Django网站,它分为几个部分。每个部分都有一组单独的导航。我正在努力解决如何最好地突出正确的问题。

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

# 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 %}

这很好......但是只有每个页面都有一个视图。例如,所有Flatpages都没有。

我会使用上下文处理器和模板标记进行回合,但似乎没什么用。有什么想法吗?

(一种显而易见的方法是将每个subnav HTML放在单独的模板中并从那些扩展到单独的页面......但我已经将模板继承用于不同类型的布局,并且添加section的维度会使问题复杂化巨大。)

1 个答案:

答案 0 :(得分:0)

我已经找到了合理的解决方案。

我制作了一个自定义assignment tag,用于设置当前页面的子导航名称:

# 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
  • 中使用named URLs
  • 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 %}

这有利于减少&#34;如果request.path = this或request.path = that或request.path = ...&#34;在模板本身。并且不依赖于任何地方的实际URL路径的好处,这对我来说似乎总是很脆弱 - 这就是命名URL的用途。

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