多行集合的Django模板中的交替行着色

Django模板提供了内置标签cycle用于在模板中的不同点处(或模板中的循环)在几个值之间交替变化,但是当在cycle定义之外的范围内访问时,此标签不会重置。 也就是说,如果您的模板中有两个或更多的列表,那么您希望使用一些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票证:循环标签超出范围后应该重置

无济于事。 (代码不适合我。)

我也尝试将我的内部循环移动到一个自定义标记,但这也不起作用,也许是因为编译/渲染循环将循环移回到外部循环? (不pipe为什么,它不适合我)。

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

最简单的解决方法(直到重置周期修补程序得到修复和应用)是使用forloop.counter内置的“divisibleby”filter:

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

稍微冗长些,但不难理解,而且效果很好。

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

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

放弃并使用Jinja2模板系统

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

编辑/注意 (我知道这听起来像是一个很小的问题,但实际上我敢打赌,你总是发现自己在Django的默认模板系统,所以这真的是值得的,我相信这会让你更有效率长远来看)。

你可以阅读由作者写的这篇文章 ,虽然它是技术性的,但他提到了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 %} 

你也可以使用mathexpression式:

 {% if x > 10 %} 

你可以直接访问你的python函数(但是需要一些设置来指定哪些函数应该暴露给模板)

 {% for item in normal_python_function_that_returns_a_query_or_a_list() %} 

甚至设置variables

 {% set variable_name = function_that_returns_an_object_or_something() %} 

我最终这样做,与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 %} 

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

有一种方法可以在服务器端使用迭代器,而不会同时复制所有条目:

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