【问题标题】:Alternate Row Coloring in Django Template with More Than One Set of RowsDjango 模板中具有多于一组行的交替行着色
【发布时间】:2010-10-02 07:55:29
【问题描述】:

Django 模板提供了内置标签 cycle 用于在模板中不同点的多个值之间交替(或模板中的 for 循环),但是当在 cycle 之外的范围内访问此标签时,它不会重置s 定义。即,如果您的模板中有两个或多个列表,您希望使用一些 css 定义oddeven 的所有行,列表的第一行将在最后一个离开的地方接,而不是从选择中重新迭代(oddeven

例如,在下面的代码中,如果第一个博客的条目数为奇数,那么第二个博客中的第一个条目将以 even 开头,而我希望它以 odd 开头。

{% for blog in blogs %}
  {% for entry in blog.entries %}
    <div class="{% cycle 'odd' 'even' %}" id="{{entry.id}}">
      {{entry.text}}
    </div>
  {% endfor %}
{% endfor %}

我尝试通过修补此处提供的 resetcycle 标签来避免这种情况:

Django ticket: Cycle tag should reset after it steps out of scope

无济于事。 (代码对我不起作用。)

我也尝试将我的内部循环移动到自定义标记中,但这也不起作用,可能是因为编译/渲染循环将循环移回了外部循环? (不管为什么,它对我不起作用。)

我怎样才能完成这个简单的任务!?我不希望在我的视图中使用预编译的这些信息创建数据结构;这似乎没有必要。提前致谢。

【问题讨论】:

    标签: django django-templates


    【解决方案1】:

    您可以使用标记的cycleresetcycle(Django 1.11 中的新功能)调用(来自https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#std:templatetag-resetcycle):

    {% for blog in blogs %}
      {% cycle 'odd' 'even' as rowcolors silent %}
      {% resetcycle rowcolors %}
      {% for entry in blog.entries %}
        {% cycle rowcolors %}
        <div class="{{ rowcolors }}" id="{{entry.id}}">
          {{ entry.text }}
        </div>
      {% endfor %}
    {% endfor %}
    

    【讨论】:

      【解决方案2】:

      https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#cycle

      {% for o in some_list %}
          <tr class="{% cycle 'row1' 'row2' %}">
              ...
          </tr>
      {% endfor %}
      

      【讨论】:

      • 这应该是公认的答案,因为它使用 django 来回答问题
      【解决方案3】:

      我最终这样做了,使用 forloop.counter0 - 效果很好!

      {% for product in products %}
      
          {% if forloop.counter0|divisibleby:4 %}<div class="clear"></div>{% endif %}
      
          <div class="product {% if forloop.counter0|divisibleby:4 %}col{% else %}col20{% endif    %}">
              Lorem Ipsum is simply dummy text
          </div>
      
      {% endfor %}
      

      【讨论】:

        【解决方案4】:

        放弃使用Jinja2 Template System

        我放弃了 django 模板语言,它的用途非常有限。 Jinja2 使用与 django 模板相同的语法,但在其上添加了许多增强功能。

        EDIT/NOTE(我知道这听起来像是一个小问题的大转变,但实际上我敢打赌你总是发现自己在与 django 中的默认模板系统作斗争,所以这真的很值得而且我相信从长远来看它会让你更有效率。)

        你可以阅读this article written by its author,虽然是技术性的,但他提到了django中{% cycle %}标签的问题。

        Jinja 没有循环标签,它在循环上有一个循环方法:

        {% for user in users %}
            <li class="{{ loop.cycle('odd', 'even') }}">{{ user }}</li>
        {% endfor %}
        

        Jinja2 的一个主要优点是它允许您使用逻辑进行演示,因此如果您有一个图片列表,您可以将它们放在一个表格中,因为您可以在表格中每隔 N 个元素开始一个新行,看,你可以做例如:

        {% if loop.index is divisibleby(5) %}   
             </tr>
             {% if not loop.last %}
             <tr>
             {% endif %}
        {% endif %}
        

        你也可以使用数学表达式:

        {% if x > 10 %}
        

        您可以直接访问您的 python 函数(但需要一些设置来指定应该为模板公开哪些函数)

        {% for item in normal_python_function_that_returns_a_query_or_a_list() %}
        

        甚至设置变量..

        {% set variable_name = function_that_returns_an_object_or_something() %} 
        

        【讨论】:

        • 对于这样一个小问题,这是一个很大的转变(有一些重大的复杂性,如第三方或贡献应用程序)。 -1
        • 提出来的好点。问题是,我敢打赌,人们总是发现自己在与 django 模板系统作斗争,这不仅仅是这个或那个小问题,而是一大堆烦恼。
        • 感谢您的建议和文章;我对 Django 的模板化方法感到有限,并且对它的错误感到恼火。但 Django 总体上很可爱。
        • 我知道,其实我喜欢 Django。这不像我说要扔 django,只需将 Jinja2 插入其环境即可。 :)
        • 我一直很高兴使用 Jinja2 模板,但我想指出 Django 模板语言有了显着改进,我现在很高兴在新项目中使用它。现在,如果只有 Django 会实现一个浏览器内调试器......
        【解决方案5】:

        最简单的解决方法(在修复并应用 resetcycle 补丁之前)是使用带有 forloop.counter 的内置“divisibleby”过滤器:

        {% for entry in blog.entries %}
          <div class="{% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}" id="{{ entry.id }}">
            {{ entry.text }}
          </div>
        {% endfor %}
        

        有点冗长,但不难理解,而且效果很好。

        【讨论】:

        • 也可以写得更短一些(至少在 Django 1.3 中):{{forloop.counter|divisibleby:2|yesno:"even,odd"}}
        • 很好的增强,迈克尔!我从来没有真正使用过 yesno 过滤器,但我认为我的模板中有很多 if/else 可以通过这种方式缩短。
        • 查看下面的答案:{% cycle 'row1' 'row2' %} 那是一种更好的解决方案,也更易于阅读。 (这个带有forloop的就是无缘无故地重新发明轮子)
        【解决方案6】:

        有一种方法可以在服务器端使用不保留所有条目的同时副本的迭代器:

        import itertools
        return render_to_response('template.html',
          {
            "flattened_entries": itertools.chain(*(blog.entries for blog in blogs)),
          })
        

        【讨论】:

        • 这如何解决 OP 的问题?似乎这只是提供错误行为的另一种方式(交替的行颜色不会在博客文章之间重置)。 -1
        【解决方案7】:

        最简单的答案可能是:“放弃并使用 jQuery。”如果这是可以接受的,那可能比与 Django 的模板为这么简单的事情争吵要容易。

        【讨论】:

        • 这就是我所做的,虽然因为我一直在使用 jQuery,所以它很简单。
        猜你喜欢
        • 2010-09-06
        • 1970-01-01
        • 2011-01-19
        • 2011-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多