【问题标题】:Compare request.path with a reversed url in Django template将 request.path 与 Django 模板中的反向 url 进行比较
【发布时间】:2012-05-03 01:22:46
【问题描述】:

我知道request.path 会给我当前的网址。

我目前正在使用带有 CSS 选项卡的 base.html 模板,我希望模板知道哪个选项卡当前处于“活动状态”并将 class="active-tab" 传递给 <a> 标记。

所以我想做类似的事情

<a href="{% url orders_list %}"
    {% if request.path = reverse('orders_list') %}
        class="active-tab"
    {$ endif %}
>Orders</a>

但我确定你不能这样做 if 比较。我也只想要忽略任何 GET 参数的基本 (?) URL。

也欢迎任何建议或提示。提前致谢!

【问题讨论】:

    标签: python django django-templates


    【解决方案1】:

    您可以在视图中计算您需要的任何内容(例如request.path = reverse('orders_list'))并将结果传递给模板。在视图(python 代码)中,您可以随意操作路径。

    您可以检查一个 URL 是否是另一个 URL 的前缀。

    【讨论】:

      【解决方案2】:

      我在 jQuery 中找到了一种破解方法......但我仍然愿意寻求更好的解决方案。

      jQuery:

      var tab_list = {
          'orders-tab' : '{% url orders_list %}',
          'users-tab'  : '{% url users_list %}',
          'vendors-tab': '{% url vendors_list %}',
          'places-tab' : '{% url places_list %}'
      }
      
      $(document).ready(function() {
          for(var property in tab_list) {
              if('{{ request.path }}' == tab_list[property]) {
                  $('#' + property).addClass('active-tab')
                  break
              }
          }
      })
      

      HTML:

      <ul id="tabs" class="fl">
          <li><a href="#" id="dashboard-tab" class="dashboard-tab">Dashboard</a></li>
          <li><a href="{% url orders_list %}" id="orders-tab">Orders</a></li>
          <li><a href="{% url users_list %}" id="users-tab">Users</a></li>
          <li><a href="{% url vendors_list %}" id="vendors-tab">Vendors</a></li>
          <li><a href="{% url places_list %}" id="places-tab">Places</a></li>
      </ul>
      

      【讨论】:

        【解决方案3】:

        您可以使用custom template tag

        from django import template
        
        register = template.Library()
        
        @register.simple_tag
        def active(request, pattern):
            path = request.path
            if path == pattern:
                return 'active'
            return ''
        

        然后在您的模板中使用有点像这样:

        {% load my_tags %}
        
        {% url orders_list as orders %}
        <li class="{% active request orders %}"> 
            <a href="{{ orders }}"> Orders </a> 
        </li>
        

        你可以随意修改模板标签。

        【讨论】:

          【解决方案4】:

          试试这个 jQuery 语句:

          $("[href='{{ request.path }}']").parents("li").addClass('active');
          

          【讨论】:

            【解决方案5】:

            灵感来自美洲狮的回答:

            $("ul.nav [href='"+window.location.pathname+"']").parents("li").addClass('active');
            

            这个解决方案是纯 JS,适用于 Bootstrap 的导航栏。对于 OP 的场景,可以使用:

            $("[href='"+window.location.pathname+"']").addClass('active-tab');
            

            【讨论】:

              【解决方案6】:

              基于 Josh 的回答,您可以使用简单的“if”标签:

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

              【讨论】:

              • 我认为这应该是公认的答案,因为它是实现预期结果的最简单方法。感谢您的帮助!
              【解决方案7】:

              最佳答案的更好版本是反转视图名称:

              {% url_active 'reverse_viewname' %}
              

              此版本不要求您传入request。相反,我们指出标签需要上下文,然后从中获取请求。

              from django import template
              from django.core.urlresolvers import reverse
              
              register = template.Library()
              
              @register.simple_tag(takes_context=True)
              def url_active(context, viewname):
                  request = context['request']
                  current_path = request.path
                  compare_path = reverse(viewname)
                  if current_path == compare_path:
                      return 'active'
                  else:
                      return ''
              

              【讨论】:

                【解决方案8】:

                用法:{% url_active "home" "other-view" "and-so-on" success="active-specific-class" %}

                from django import template
                
                register = template.Library()
                
                
                @register.simple_tag(takes_context=True)
                def url_active(context, *args, **kwargs):
                    if 'request' not in context:
                        return ''
                
                    request = context['request']
                    if request.resolver_match.url_name in args:
                        return kwargs['success'] if 'success' in kwargs else 'active'
                    else:
                        return ''
                

                【讨论】:

                  【解决方案9】:

                  带有 if-then-else 选项的解决方案:

                  from django import template
                  from django.template.base import Node, NodeList, TemplateSyntaxError
                  
                  register = template.Library()
                  
                  class IfCurrentViewNode(Node):
                      child_nodelists = ('nodelist_true', 'nodelist_false')
                  
                      def __init__(self, view_name, nodelist_true, nodelist_false):
                          self.view_name = view_name
                          self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
                  
                      def __repr__(self):
                          return "<IfCurrentViewNode>"
                  
                      def render(self, context):
                          view_name = self.view_name.resolve(context, True)
                          request = context['request']
                          if request.resolver_match.url_name == view_name:
                              return self.nodelist_true.render(context)
                          return self.nodelist_false.render(context)
                  
                  
                  def do_ifcurrentview(parser, token):
                      bits = token.split_contents()
                      if len(bits) < 2:
                          raise TemplateSyntaxError("'%s' takes at least one argument"
                                                    " (path to a view)" % bits[0])
                      view_name = parser.compile_filter(bits[1])
                      nodelist_true = parser.parse(('else', 'endifcurrentview'))
                      token = parser.next_token()
                      if token.contents == 'else':
                          nodelist_false = parser.parse(('endifcurrentview',))
                          parser.delete_first_token()
                      else:
                          nodelist_false = NodeList()
                      return IfCurrentViewNode(view_name, nodelist_true, nodelist_false)
                  
                  @register.tag
                  def ifcurrentview(parser, token):
                      """
                      Outputs the contents of the block if the current view match the argument.
                  
                      Examples::
                  
                          {% ifcurrentview 'path.to.some_view' %}
                              ...
                          {% endifcurrentview %}
                  
                          {% ifcurrentview 'path.to.some_view' %}
                              ...
                          {% else %}
                              ...
                          {% endifcurrentview %}
                      """
                      return do_ifcurrentview(parser, token)
                  

                  【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-04-06
                  • 2019-01-19
                  • 2020-02-08
                  • 2019-09-21
                  • 1970-01-01
                  • 2013-03-04
                  相关资源
                  最近更新 更多