Django模板中的备用行着色具有多个行集

时间:2009-01-19 21:05:22

标签: django django-templates

Django模板提供了内置标记cycle,用于在模板中的不同点(或模板中的循环)中的多个值之间交替,但是当在{范围外的范围内访问此标记时,此标记不会重置{1}}的定义。也就是说,如果您的模板中有两个或更多列表,那么您想要使用一些css定义cycleodd的所有行,列表的第一行将会在哪里找到最后一个关闭,而不是选择中的新迭代(evenodd

例如,在以下代码中,如果第一个博客的条目数量为奇数,那么第二个博客中的第一个条目将以even开头,当我希望它从even开始时

odd

我尝试通过修补此处提供的{% for blog in blogs %} {% for entry in blog.entries %} <div class="{% cycle 'odd' 'even' %}" id="{{entry.id}}"> {{entry.text}} </div> {% endfor %} {% endfor %} 标记来避免这种情况:

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

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

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

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

7 个答案:

答案 0 :(得分:111)

最简单的解决方法(直到重置补丁修复并应用)是使用带有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 %}

更冗长,但不难理解,效果很好。

答案 1 :(得分:14)

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

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

答案 2 :(得分:3)

您可以使用已标记的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 %}

答案 3 :(得分:2)

我最终这样做了,使用了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 :(得分:1)

最简单的答案可能是:“放弃并使用jQuery。”如果这是可以接受的,那么可能比使用Django的模板更容易实现这么简单。

答案 5 :(得分:1)

放弃并使用Jinja2 Template System

我放弃了django模板语言,它对你可以用它做什么非常有限。 Jinja2使用与django模板相同的语法,但增加了许多增强功能。

编辑/注意(我知道这对于一个小问题来说听起来像是一个很大的转变,但实际上我打赌你总是发现自己在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() %} 

答案 6 :(得分:-5)

有一种方法可以在服务器端使用迭代器来完成所有条目的同时复制:

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