Навигация в Джанго

Я только что сделал свой первый маленький веб-приложение в Django, и мне это нравится. Я собираюсь начать преобразование старого производственного сайта PHP в django, и как часть его шаблона, есть панель навигации.

В PHP я проверяю URL каждого параметра навигации по текущему URL в коде шаблона и применяю класс CSS, если они совпадают. Это ужасно грязно.

Есть ли что-то лучше для django или хороший способ обработки кода в шаблоне?

Для начала, как мне получить текущий URL?

28 ответов

Решение

Я использую наследование шаблонов для настройки навигации. Например:

base.html

<html>
    <head>...</head>
    <body>
        ...
        {% block nav %}
        <ul id="nav">
            <li>{% block nav-home %}<a href="{% url home %}">Home</a>{% endblock %}</li>
            <li>{% block nav-about %}<a href="{% url about %}">About</a>{% endblock %}</li>
            <li>{% block nav-contact %}<a href="{% url contact %}">Contact</a>{% endblock %}</li>
        </ul>
        {% endblock %}
        ...
    </body>
</html>

about.html

{% extends "base.html" %}

{% block nav-about %}<strong class="nav-active">About</strong>{% endblock %}

Вам не нужно, если это сделать, посмотрите на следующий код:

tags.py

@register.simple_tag
def active(request, pattern):
    import re
    if re.search(pattern, request.path):
        return 'active'
    return ''

urls.py

urlpatterns += patterns('',
    (r'/$', view_home_method, 'home_url_name'),
    (r'/services/$', view_services_method, 'services_url_name'),
    (r'/contact/$', view_contact_method, 'contact_url_name'),
)

base.html

{% load tags %}

{% url 'home_url_name' as home %}
{% url 'services_url_name' as services %}
{% url 'contact_url_name' as contact %}

<div id="navigation">
    <a class="{% active request home %}" href="{{ home }}">Home</a>
    <a class="{% active request services %}" href="{{ services }}">Services</a>
    <a class="{% active request contact %}" href="{{ contact }}">Contact</a>
</div>

вот и все. для деталей реализации взгляните на:
gnuvince.wordpress.com
110j.wordpress.com

Мне понравилась чистота выше 110j, поэтому я взял большую ее часть и провел рефакторинг, чтобы решить 3 проблемы, которые у меня были:

  1. регулярное выражение сопоставляло домашний URL со всеми остальными
  2. Мне нужно было несколько URL, привязанных к одной вкладке навигации, поэтому мне нужен был более сложный тег, который принимает переменное количество параметров
  3. исправлены некоторые проблемы с URL

Вот:

tags.py:

from django import template

register = template.Library()

@register.tag
def active(parser, token):
    args = token.split_contents()
    template_tag = args[0]
    if len(args) < 2:
        raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
    return NavSelectedNode(args[1:])

class NavSelectedNode(template.Node):
    def __init__(self, patterns):
        self.patterns = patterns
    def render(self, context):
        path = context['request'].path
        for p in self.patterns:
            pValue = template.Variable(p).resolve(context)
            if path == pValue:
                return "active" # change this if needed for other bootstrap version (compatible with 3.2)
        return ""

urls.py:

urlpatterns += patterns('',
    url(r'/$', view_home_method, {}, name='home_url_name'),
    url(r'/services/$', view_services_method, {}, name='services_url_name'),
    url(r'/contact/$', view_contact_method, {}, name='contact_url_name'),
    url(r'/contact/$', view_contact2_method, {}, name='contact2_url_name'),
)

base.html:

{% load tags %}

{% url home_url_name as home %}
{% url services_url_name as services %}
{% url contact_url_name as contact %}
{% url contact2_url_name as contact2 %}

<div id="navigation">
    <a class="{% active request home %}" href="home">Home</a>
    <a class="{% active request services %}" href="services">Services</a>
    <a class="{% active request contact contact2 %}" href="contact">Contact</a>
</div>

Я автор django-lineage, который я написал специально для решения этого вопроса:D

Меня раздражало использование (вполне приемлемого) метода jpwatts в моих собственных проектах, и я черпал вдохновение в ответе 110j. Lineage выглядит так:

{% load lineage %}
<div id="navigation">
    <a class="{% ancestor '/home/' %}" href="/home/">Home</a>
    <a class="{% ancestor '/services/' %}" href="/services/">Services</a>
    <a class="{% ancestor '/contact/' %}" href="/contact/">Contact</a>
</div>

ancestor просто заменяется на "активный", если аргумент соответствует началу текущей страницы URL.

Переменные аргументы и полные {% url %} Тип обратного разрешения, также поддерживается. Я набросал несколько вариантов конфигурации, немного уточнил и упаковал их для всех.

Если кому-то интересно, читайте об этом подробнее по адресу:

>> https://github.com/marcuswhybrow/django-lineage

С Джанго 1.5:

Во всех общих представлениях на основе классов (или в любом представлении на основе классов, унаследованном от ContextMixin), словарь контекста содержит переменную представления, которая указывает на экземпляр View.

Так что, если вы используете такие представления, вы можете добавить что-то вроде breadcrumbs как поле уровня класса и использовать его в своих шаблонах.

Пример вида кода:

class YourDetailView(DetailView):
     breadcrumbs = ['detail']
     (...)

В вашем шаблоне вы можете использовать его следующим образом:

<a href="/detail/" {% if 'detail' in view.breadcrumbs %}class="active"{% endif %}>Detail</a>

Если вы хотите дополнительно "выделить" родительские элементы навигации, вам необходимо расширить breadcrumbs список:

class YourDetailView(DetailView):
     breadcrumbs = ['dashboard', 'list', 'detail']
     (...)

... и в вашем шаблоне:

<a href="/dashboard/" {% if 'dashboard' in view.breadcrumbs %}class="active"{% endif %}>Dashboard</a>
<a href="/list/" {% if 'list' in view.breadcrumbs %}class="active"{% endif %}>List</a>
<a href="/detail/" {% if 'detail' in view.breadcrumbs %}class="active"{% endif %}>Detail</a>

Это простое и понятное решение, которое отлично работает с вложенной навигацией.

Вы можете применить класс или идентификатор к элементу body страницы, а не к конкретному элементу навигации.

HTML:

<body class="{{ nav_class }}">

CSS:

body.home #nav_home,
body.about #nav_about { */ Current nav styles */ }

Я делаю это так:

<a class="tab {% ifequal active_tab "statistics" %}active{% endifequal %}" href="{% url Member.Statistics %}">Statistics</a>

и тогда все, что мне нужно сделать, это на мой взгляд добавить {'active_tab': 'statistics'} в мой контекстный словарь.

Если вы используете RequestContext Вы можете получить текущий путь в вашем шаблоне как:

{{ request.path }}

И по вашему мнению:

from django.template import RequestContext

def my_view(request):
    # do something awesome here
    return template.render(RequestContext(request, context_dict))

Я взял код из nivhab выше и удалил некоторые странности и превратил его в чистый тег шаблона, изменил его так, чтобы /account/edit/ все еще делал /account/ tab активным.

#current_nav.py
from django import template

register = template.Library()

@register.tag
def current_nav(parser, token):
    import re
    args = token.split_contents()
    template_tag = args[0]
    if len(args) < 2:
        raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
    return NavSelectedNode(args[1])

class NavSelectedNode(template.Node):
    def __init__(self, url):
        self.url = url

    def render(self, context):
        path = context['request'].path
        pValue = template.Variable(self.url).resolve(context)
        if (pValue == '/' or pValue == '') and not (path  == '/' or path == ''):
            return ""
        if path.startswith(pValue):
            return ' class="current"'
        return ""



#template.html
{% block nav %}
{% load current_nav %}
{% url home as home_url %}
{% url signup as signup_url %}
{% url auth_login as auth_login_url %}
<ul class="container">
    <li><a href="{{ home_url }}"{% current_nav home_url %} title="Home">Home</a></li>
    <li><a href="{{ auth_login_url }}"{% current_nav auth_login_url %} title="Login">Login</a></li>
    <li><a href="{{ signup_url }}"{% current_nav signup_url %} title="Signup">Signup</a></li>
</ul>
{% endblock %}

Это всего лишь вариант решения CSS, предложенного Toba выше:

Включите в свой базовый шаблон следующее:

<body id="section-{% block section %}home{% endblock %}">

Тогда в ваших шаблонах, которые расширяют базовое использование:

{% block section %}show{% endblock %}

Затем вы можете использовать css для выделения текущей области на основе тега body (например, если у нас есть ссылка с идентификатором nav-home):

#section-home a#nav-home{
 font-weight:bold;
}

Вы можете использовать функцию reverse с соответствующими параметрами, чтобы получить текущий URL.

Спасибо за ваши ответы, господа. Я снова пошел на что-то немного другое..

В моем шаблоне:

<li{{ link1_active }}>...link...</li>
<li{{ link2_active }}>...link...</li>
<li{{ link3_active }}>...link...</li>
<li{{ link4_active }}>...link...</li>

После того, как я определил, на какой странице я нахожусь в логике (обычно в urls.py), я передаю class="selected" как часть контекста под правильным именем к шаблону.

Например, если я нахожусь на странице link1, я добавлю {'link1_active':' class="selected"'} в контекст для шаблона, чтобы выкопать и ввести.

Кажется, работает, и это довольно чисто.

Изменить: чтобы не допустить HTML в мой контроллер / представление, я немного изменил это:

<li{% if link1_active %} class="selected"{% endif %}>...link...</li>
<li{% if link2_active %} class="selected"{% endif %}>...link...</li>
...

Это делает шаблон немного менее читабельным, но я согласен, лучше не проталкивать необработанный HTML из файла urls.

Я обнаружил, что лучше всего использовать тег включения:

templates/fnf/nav_item.html

<li class="nav-item">
    <a class="nav-link {% if is_active %}active{% endif %}" href="{% url url_name %}">{{ link_name }}</a>
</li>

Это просто мой базовый элемент начальной загрузки, который я хочу визуализировать.

Он получает значение href и, необязательно, значение link_name. is_active рассчитывается на основе текущего запроса.

templatetags/nav.py

from django import template

register = template.Library()


@register.inclusion_tag('fnf/nav_item.html', takes_context=True)
def nav_item(context, url_name, link_name=None):
    return {
        'url_name': url_name,
        'link_name': link_name or url_name.title(),
        'is_active': context.request.resolver_match.url_name == url_name,
    }

Затем используйте его в навигации:templates/fnf/nav.html

{% load nav %}
<nav class="navbar navbar-expand-lg navbar-light bg-light">
        <ul class="navbar-nav mr-auto">
                {% nav_item 'dashboard' %}
            </ul>

Я просто хотел поделиться своим незначительным улучшением поста нивхаба. В моем приложении у меня есть поднавигаторы, и я не хотел скрывать их, используя только CSS, поэтому мне нужен был какой-то тег "если", чтобы отображать субнавигатор для элемента или нет.

from django import template
register = template.Library()

@register.tag
def ifnaviactive(parser, token):
    nodelist = parser.parse(('endifnaviactive',))
    parser.delete_first_token()

    import re
    args = token.split_contents()
    template_tag = args[0]
    if len(args) < 2:
        raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
    return NavSelectedNode(args[1:], nodelist)

class NavSelectedNode(template.Node):
    def __init__(self, patterns, nodelist):
        self.patterns = patterns
        self.nodelist = nodelist

    def render(self, context):
        path = context['request'].path
        for p in self.patterns:
            pValue = template.Variable(p).resolve(context)
            if path == pValue:
                return self.nodelist.render(context)
        return ""

Вы можете использовать это в основном так же, как активный тег:

{% url product_url as product %}

{% ifnaviactive request product %}
    <ul class="subnavi">
        <li>Subnavi item for product 1</li>
        ...
    </ul>
{% endifnaviactive %}

Я использовал jquery, чтобы выделить свои навигационные панели. Это решение просто добавляет класс css "active" к элементу, который соответствует селектору css.

<script type="text/javascript" src="/static/js/jquery.js"></script>
<script>
    $(document).ready(function(){
        var path = location.pathname;
        $('ul.navbar a.nav[href$="' + path + '"]').addClass("active");
    });
</script>

Просто еще одно преимущество оригинального решения.

Это принимает несколько шаблонов и, что лучше всего, также безымянные шаблоны, записанные в виде относительного URL, заключенного в '"', например:

{% url admin:clients_client_changelist as clients %}
{% url admin:clients_town_changelist as towns %}
{% url admin:clients_district_changelist as districts %}

<li class="{% active "/" %}"><a href="/">Home</a></li>
<li class="{% active clients %}"><a href="{{ clients }}">Clients</a></li>
{% if request.user.is_superuser %}
<li class="{% active towns districts %}">
    <a href="#">Settings</a>
    <ul>
        <li><a href="{{ towns }}">Towns</a></li>
        <li><a href="{{ districts }}">Districts</a></li>
    </ul>
</li>
{% endif %}

Тег выглядит так:

from django import template

register = template.Library()

@register.tag
def active(parser, token):
    args = token.split_contents()
    template_tag = args[0]
    if len(args) < 2:
        raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
    return NavSelectedNode(args[1:])

class NavSelectedNode(template.Node):
    def __init__(self, urls):
        self.urls = urls

    def render(self, context):
        path = context['request'].path

        for url in self.urls:
            if '"' not in url:
                cpath = template.Variable(url).resolve(context)
            else:
                cpath = url.strip('"')

            if (cpath == '/' or cpath == '') and not (path == '/' or path == ''):
                return ""
            if path.startswith(cpath):
                return 'active'
        return ""

Моим решением было написать простой контекстный процессор для установки переменной на основе пути запроса:

def navigation(request):
"""
Custom context processor to set the navigation menu pointer.
"""
nav_pointer = ''
if request.path == '/':
    nav_pointer = 'main'
elif request.path.startswith('/services/'):
    nav_pointer = 'services'
elif request.path.startswith('/other_stuff/'):
    nav_pointer = 'other_stuff'
return {'nav_pointer': nav_pointer}

(Не забудьте добавить свой пользовательский процессор в TEMPLATE_CONTEXT_PROCESSORS в settings.py.)

Затем в базовом шаблоне я использую тег ifequal для каждой ссылки, чтобы определить, добавлять ли "активный" класс. Конечно, этот подход строго ограничен гибкостью структуры вашего пути, но он подходит для моего относительно скромного развертывания.

Небольшое улучшение по сравнению с ответом @tback, без каких-либо %if% теги:

# navigation.py
from django import template
from django.core.urlresolvers import resolve

register = template.Library()

@register.filter(name="activate_if_active", is_safe=True)
def activate_if_active(request, urlname):
  if resolve(request.get_full_path()).url_name == urlname:
    return "active"
  return ''

Используйте это в своем шаблоне так:

{% load navigation %}
<li class="{{ request|activate_if_active:'url_name' }}">
  <a href="{% url 'url_name' %}">My View</a>
</li>

И включать "django.core.context_processors.request" в вашем TEMPLATE_CONTEXT_PROCESSORS установка.

У меня есть несколько меню на одной странице, которые создаются динамически через цикл. Посты выше, относящиеся к контексту, дали мне быстрое решение. Надеюсь, это кому-нибудь поможет. (Я использую это в дополнение к активному тегу шаблона - мое исправление решает проблему с динамикой). Это выглядит как глупое сравнение, но это работает. Я решил назвать переменные active_something-unique и что-то уникальное, таким образом, это работает с вложенными меню.

Вот часть представления (достаточно, чтобы понять, что я делаю):

def project_list(request, catslug):
    "render the category detail page"
    category = get_object_or_404(Category, slug=catslug, site__id__exact=settings.SITE_ID)
    context = {
        'active_category': 
            category,
        'category': 
            category,
        'category_list': 
            Category.objects.filter(site__id__exact=settings.SITE_ID),

    }

И это из шаблона:

<ul>
  {% for category in category_list %}
    <li class="tab{% ifequal active_category category %}-active{% endifequal %}">
      <a href="{{ category.get_absolute_url }}">{{ category.cat }}</a>
    </li>
  {% endfor %}
</ul>

Вдохновленный этим решением, я начал использовать этот подход:

**Placed in templates as base.html**

{% block tab_menu %}
<ul class="tab-menu">
  <li class="{% if active_tab == 'tab1' %} active{% endif %}"><a href="#">Tab 1</a></li>
  <li class="{% if active_tab == 'tab2' %} active{% endif %}"><a href="#">Tab 2</a></li>
  <li class="{% if active_tab == 'tab3' %} active{% endif %}"><a href="#">Tab 3</a></li>
</ul>
{% endblock tab_menu %}

**Placed in your page template**

{% extends "base.html" %}

{% block tab_menu %}
  {% with active_tab="tab1" %} {{ block.super }} {% endwith %}
{% endblock tab_menu %}

Я знаю, что опоздал на вечеринку. Мне не понравилось ни одно из популярных решений:

Блочный метод кажется неправильным: я думаю, что навигация должна быть автономной.

Метод template_tag кажется неправильным: мне не нравится, что я должен сначала получить URL-адрес из URL-тега. Кроме того, я думаю, что класс CSS должен быть определен в шаблоне, а не в теге.

Поэтому я написал фильтр, у которого нет недостатков, которые я описал выше. Возвращается True если URL активен и поэтому может использоваться с {% if %}:

{% load navigation %}
<li{% if request|active:"home" %} class="active"{% endif %}><a href="{% url "home" %}">Home</a></li>

Код:

@register.filter(name="active")
def active(request, url_name):
    return resolve(request.path_info).url_name == url_name

Просто убедитесь, что используете RequestContext на страницах с навигацией или чтобы включить запрос context_processor в вашем settings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    'django.core.context_processors.request',
)

Немного изменив ответ Андреаса, похоже, вы можете передать имя маршрута от urls.py до тега шаблона. В моем примере my_tasks, а затем в функции тега шаблона используйте функцию reverse, чтобы определить, каким должен быть URL, затем вы можете сопоставить это с URL в объекте запроса (доступно в контексте шаблона).

from django import template
from django.core.urlresolvers import reverse

register = template.Library()

@register.tag
def active(parser, token):
    args = token.split_contents()
    template_tag = args[0]
    if len(args) < 2:
        raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
    return NavSelectedNode(args[1:])

class NavSelectedNode(template.Node):
    def __init__(self, name):
        self.name = name

    def render(self, context):

        if context['request'].path == reverse(self.name[1]):
            return 'active'
        else:
            return ''

urls.py

url(r'^tasks/my', my_tasks, name = 'my_tasks' ),

template.html

<li class="{% active request all_tasks %}"><a href="{% url all_tasks %}">Everyone</a></li>

Я видел ответы jpwatts', 110j' s, nivhab& Marcus Whybrow, но все они, похоже, чего-то не хватает: как насчет корневого пути? Почему это всегда активно?

Так что я сделал другой, более простой способ, который заставляет "контроллер" решать сам, и я думаю, что он решает большинство больших проблем.

Вот мой пользовательский тег:

## myapp_tags.py

@register.simple_tag
def nav_css_class(page_class):
    if not page_class:
        return ""
    else:
        return page_class

Затем "контроллер" объявляет необходимые классы CSS (на самом деле, самое важное, он объявляет о своем присутствии в шаблоне)

## views.py

def ping(request):
    context={}
    context["nav_ping"] = "active"
    return render(request, 'myapp/ping.html',context)

И, наконец, я отображаю это в моей панели навигации:

<!-- sidebar.html -->

{% load myapp_tags %}
...

<a class="{% nav_css_class nav_home %}" href="{% url 'index' %}">
    Accueil
</a>
<a class="{% nav_css_class nav_candidats %}" href="{% url 'candidats' %}">
    Candidats
</a>
<a class="{% nav_css_class nav_ping %}" href="{% url 'ping' %}">
    Ping
</a>
<a class="{% nav_css_class nav_stat %}" href="{% url 'statistiques' %}">
    Statistiques
</a>
...

Так что каждая страница имеет свою nav_css_class значение для установки, и если оно установлено, шаблон становится активным: нет необходимости request в контексте шаблона не нужно разбирать URL-адреса и больше не возникает проблем со страницами с несколькими URL или корневой страницей.

Из этого ТАКОГО вопроса

{% url 'some_urlpattern_name' as url %}
<a href="{{url}}"{% if request.path == url %} class="active"{% endif %}>Link</a>

Повторите по мере необходимости для каждой ссылки.

Мой немного похож на другой подход JS, представленный ранее... просто без jQuery...

Скажем, у нас есть в base.html следующее:

<div class="pure-u-1 pure-menu pure-menu-open pure-menu-horizontal header" >
    <ul class="">
        <li id="home"><a href="{% url 'article:index' %}">Home</a></li>
        <li id="news"><a href="{% url 'article:index' %}">News</a></li>
        <li id="analysis"><a href="{% url 'article:index' %}">Analysis</a></li>
        <li id="opinion"><a href="{% url 'article:index' %}">Opinion</a></li>
        <li id="data"><a href="{% url 'article:index' %}">Data</a></li>
        <li id="events"><a href="{% url 'article:index' %}">Events</a></li>
        <li id="forum"><a href="{% url 'article:index' %}">Forum</a></li>
        <li id="subscribe"><a href="{% url 'article:index' %}">Subscribe</a></li>
    </ul>
    <script type="text/javascript">
        (function(){
            loc=/\w+/.exec(window.location.pathname)[0];
            el=document.getElementById(loc).className='pure-menu-selected';         
        })();   
    </script>
</div>

Я просто создал свою иерархию, чтобы следовать определенному шаблону URL... после адреса хоста... у меня есть моя основная категория, например, дом, новости, анализ и т. Д., И регулярное выражение просто вытаскивает первое слово из местоположения

Я также использовал jQuery, чтобы выделить его и найти его более элегантным, чем загромождать шаблон несемантическими тегами шаблонов Django.

Приведенный ниже код работает с вложенными раскрывающимися списками в начальной загрузке 3 (выделяет как родительский, так и дочерний <li> элемент.

// DOM Ready
$(function() {
    // Highlight current page in nav bar
    $('.nav, .navbar-nav li').each(function() {
        // Count the number of links to the current page in the <li>
        var matched_links = $(this).find('a[href]').filter(function() {
            return $(this).attr('href') == window.location.pathname; 
        }).length;
        // If there's at least one, mark the <li> as active
        if (matched_links)
            $(this).addClass('active');
    });
});

Это также довольно легко добавить click событие в return false (или измените href приписывать #) для текущей страницы, без изменения разметки шаблона /html:

        var matched_links = $(this).find('a[href]').filter(function() {
            var matched = $(this).attr('href') == window.location.pathname;
            if (matched)
                $(this).click(function() { return false; });
            return matched;
        }).length;

Вот довольно простое решение, https://github.com/hellysmile/django-activeurl

Вот мой путь. В итоге я реализовал класс в моих представлениях, который содержит мою структуру навигации (плоская с некоторыми метаданными). Затем я вставляю это в шаблон и выводю его.

Мое решение касается i18n. Это, вероятно, должно быть абстрагировано немного больше, но я не особо беспокоился об этом.

views.py:

from django.utils.translation import get_language, ugettext as _


class Navi(list):
    items = (_('Events'), _('Users'), )

    def __init__(self, cur_path):
        lang = get_language()
        first_part = '/' + cur_path.lstrip('/').split('/')[0]

        def set_status(n):
            if n['url'] == first_part:
                n['status'] == 'active'

        for i in self.items:
            o = {'name': i, 'url': '/' + slugify(i)}
            set_status(o)
            self.append(o)

# remember to attach Navi() to your template context!
# ie. 'navi': Navi(request.path)

Я определил логику шаблона с помощью включений следующим образом. Базовый шаблон:

{% include "includes/navigation.html" with items=navi %}

Фактическое включение (includes/navigation.html):

 <ul class="nav">
     {% for item in items %}
         <li class="{{ item.status }}">
             <a href="{{ item.url }}">{{ item.name }}</a>
         </li>
     {% endfor %}
 </ul>

Надеюсь, кто-то найдет это полезным! Я думаю, было бы довольно легко расширить эту идею для поддержки вложенных иерархий и т. Д.

Я использую комбинацию этого миксина для представлений на основе классов:

class SetActiveViewMixin(object):
    def get_context_data(self, **kwargs):
        context = super(SetActiveViewMixin, self).get_context_data(**kwargs)
        context['active_nav_menu'] = {
            self.request.resolver_match.view_name: ' class="pure-menu-selected"'
        }
        return context

с этим в шаблоне:

<ul>
    <li{{active_nav_menu.node_explorer }}><a href="{% url 'node_explorer' '' %}">Explore</a></li>
    <li{{active_nav_menu.node_create }}><a href="{% url 'node_create' path %}">Create</a></li>
    <li{{active_nav_menu.node_edit }}><a href="{% url 'node_edit' path %}">Edit</a></li>
    <li{{active_nav_menu.node_delete }}><a href="{% url 'node_delete' path %}">Delete</a></li>
</ul>

**

Просто добавьте URL и имя в формате jinja, как это

**

 <ul class="nav navbar-nav">
        <li>
           <a href="{% url 'index' %}">Cities</a>
        </li>
        <li>
           <a href="{% url 'all_cafes' %}">Cafes</a>
        </li>
    </ul>

Создайте включаемый шаблон "intranet/nav_item.html":

{% load url from future %}

{% url view as view_url %}
<li class="nav-item{% ifequal view_url request.path %} current{% endifequal %}">
    <a href="{{ view_url }}">{{ title }}</a>
</li>

И включите его в элемент nav:

<ul>
    {% include "intranet/nav_item.html" with view='intranet.views.home' title='Home' %}
    {% include "intranet/nav_item.html" with view='crm.views.clients' title='Clients' %}
</ul>

И вам нужно добавить это в настройках:

from django.conf import global_settings
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
    'django.core.context_processors.request',
)
Другие вопросы по тегам