在Django航行

Oli*_*Oli 99 navigation django

我刚刚在django完成了我的第一个小webapp,我喜欢它.我即将开始将旧的生产PHP站点转换为django,作为其模板的一部分,还有一个导航栏.

在PHP中,我在模板代码中检查每个导航选项的URL与当前URL,如果它们对齐,则应用CSS类.这太可怕了.

是否有更好的django或处理模板中的代码的好方法?

首先,我将如何获取当前的URL?

小智 114

您不需要if,请查看以下代码:

tags.py

@register.simple_tag
def active(request, pattern):
    import re
    if re.search(pattern, request.path):
        return 'active'
    return ''
Run Code Online (Sandbox Code Playgroud)

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'),
)
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

而已.有关实现的详细信息,请查看:
gnuvince.wordpress.com
110j.wordpress.com

  • 不要忘记将`django.core.context_processors.request`添加到`settings.py`中的`TEMPLATE_CONTEXT_PROCESSORS` (5认同)
  • @Keyo,在项目中创建templatetags目录,并将项目添加到installedapps.这也将成功.或者,就像你说的那样,将你的主站点创建为项目中的应用程序. (3认同)
  • href的属性缺少django模板括号{{,}}.例如,<a class="{% active request home %}" href="home">主页</a>应为,<a class ="{%active request home%}"href ="{{home} }">主页</a> tags.py文件还需要一些包含.否则,很棒的解决方案 (2认同)
  • +1这与应用程序的松散耦合.作为初学者,我发现标签需要它自己的应用程序,你不能只将其转储到全局的tags.py文件中.我创建了一个名为tags的新应用程序,一切顺利.http://docs.djangoproject.com/en/dev/howto/custom-template-tags/ (2认同)

jpw*_*tts 74

我使用模板继承来自定义导航.例如:

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>
Run Code Online (Sandbox Code Playgroud)

about.html

{% extends "base.html" %}

{% block nav-about %}<strong class="nav-active">About</strong>{% endblock %}
Run Code Online (Sandbox Code Playgroud)

  • 我并不热衷于这种方法,因为同一个子模板处理多个网站部分并不罕见.因此,您最终会在模板中的视图和条件中放置自定义变量,或者重新排列子模板,以便它们都是唯一的...只是为了检测当前站点部分.模板标签方法最终变得更加清洁. (21认同)

niv*_*hab 33

我喜欢上面的110j的清洁度,所以我把它的大部分用于解决我遇到的3个问题并进行了重构:

  1. 正则表达式将"主页"网址与其他所有网址相匹配
  2. 我需要多个URL映射到一个导航选项卡,所以我需要一个更复杂的标签,它需要不同数量的参数
  3. 修复了一些网址问题

这里是:

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 ""
Run Code Online (Sandbox Code Playgroud)

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'),
)
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)


Mar*_*row 20

我是django-lineage的作者,我是专门为解决这个问题写的:D

我在自己的项目中使用(完全可以接受的)jpwatts方法变得恼火,并从110j的答案中汲取灵感.天堂看起来像这样:

{% 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>
Run Code Online (Sandbox Code Playgroud)

ancestor 如果参数与当前页面URL的开头匹配,则简单地将其替换为"active".

{% url %}还支持变量参数和完整类型反向分辨率.我在一些配置选项中添加了一些选项,并将其打包并打包以供所有人使用.

如果有人有兴趣,请阅读以下内容:

>> github.com/marcuswhybrow/django-lineage

  • 将路径硬编码到模板中:( (2认同)

Kon*_*łas 10

Django 1.5开始:

在所有基于类的通用视图(或从ContextMixin继承的任何基于类的视图)中,上下文字典包含指向View实例的视图变量.

因此,如果您使用此类视图,则可以添加类似于breadcrumbs类级别字段的内容并在模板中使用它.

示例视图代码:

class YourDetailView(DetailView):
     breadcrumbs = ['detail']
     (...)
Run Code Online (Sandbox Code Playgroud)

在您的模板中,您可以通过以下方式使用它:

<a href="/detail/" {% if 'detail' in view.breadcrumbs %}class="active"{% endif %}>Detail</a>
Run Code Online (Sandbox Code Playgroud)

如果要另外"突出显示"父导航项,则需要扩展breadcrumbs列表:

class YourDetailView(DetailView):
     breadcrumbs = ['dashboard', 'list', 'detail']
     (...)
Run Code Online (Sandbox Code Playgroud)

...并在您的模板中:

<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>
Run Code Online (Sandbox Code Playgroud)

这是简单而干净的解决方案,适用于嵌套导航.


Mic*_*tin 9

您可以将类或id应用于页面的body元素,而不是应用于特定的nav项.

HTML:

<body class="{{ nav_class }}">
Run Code Online (Sandbox Code Playgroud)

CSS:

body.home #nav_home,
body.about #nav_about { */ Current nav styles */ }
Run Code Online (Sandbox Code Playgroud)


muh*_*huk 8

我是这样做的:

<a class="tab {% ifequal active_tab "statistics" %}active{% endifequal %}" href="{% url Member.Statistics %}">Statistics</a>
Run Code Online (Sandbox Code Playgroud)

然后我所要做的就是在我的视图中添加{'active_tab': 'statistics'}到我的上下文字典中.

如果您正在使用RequestContext,则可以在模板中获取当前路径:

{{ request.path }}
Run Code Online (Sandbox Code Playgroud)

在你看来:

from django.template import RequestContext

def my_view(request):
    # do something awesome here
    return template.render(RequestContext(request, context_dict))
Run Code Online (Sandbox Code Playgroud)


And*_*eas 7

我从上面的nivhab获取了代码并删除了一些wierdness并将其变成了一个干净的模板标签,修改它以便/ 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 %}
Run Code Online (Sandbox Code Playgroud)


dtt*_*101 6

这只是Toba上面提出的css解决方案的一个变种:

在基本模板中包含以下内容:

<body id="section-{% block section %}home{% endblock %}">
Run Code Online (Sandbox Code Playgroud)

然后在扩展基本用途的模板中:

{% block section %}show{% endblock %}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用css根据body标签突出显示当前区域(例如,如果我们有一个id为nav-home的链接):

#section-home a#nav-home{
 font-weight:bold;
}
Run Code Online (Sandbox Code Playgroud)