Django模板提供了内置标记cycle
,用于在模板中的不同点(或模板中的循环)中的多个值之间交替,但是当在{范围外的范围内访问此标记时,此标记不会重置{1}}的定义。也就是说,如果您的模板中有两个或更多列表,那么您想要使用一些css定义cycle
和odd
的所有行,列表的第一行将会在哪里找到最后一个关闭,而不是选择中的新迭代(even
和odd
)
例如,在以下代码中,如果第一个博客的条目数量为奇数,那么第二个博客中的第一个条目将以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
无济于事。 (该代码对我不起作用。)
我也尝试将内部循环移动到自定义标记中,但这也无效,可能是因为编译/渲染循环将循环移回外部循环? (无论为什么,它对我都不起作用。)
我怎样才能完成这个简单的任务!?我不希望在我的视图中使用预先编译的信息创建数据结构;这似乎没必要。提前谢谢。
答案 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)
您可以使用已标记的cycle
和resetcycle
(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)
我放弃了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)),
})