2009-01-19 25 views
57

Django模板提供内置标记cycle,用于在模板中的不同点之间交替使用多个值(或用于模板中的循环),但此标记在其重置时不会重置在范围之外的范围内访问。也就是说,如果您的模板中有两个或更多列表,那么您希望使用某些css定义oddeven的所有行,列表的第一行将会从最后一个离开的位置开始拾取,而不是从选择新鲜的迭代(oddevenDjango模板中具有多行设置的替代行着色

例如,在下面的代码,如果第一个博客有奇数个条目,然后在第二个博客的第一项将开始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

无济于事。 (代码没有为我工作。)

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

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

回答

109

最简单的解决办法(直到resetcycle补丁被固定起来,并应用)是使用内置的“divisibleby”过滤器forloop.counter:

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

有点冗长,但不难理解,它的效果很好。

1

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

+0

这是我做的,但因为我是无论如何使用jQuery,这是相当微不足道的。 – 2009-01-20 04:06:35

2

放弃和使用Jinja2 Template System

我放弃了在Django的模板语言,它是非常的,你可以用它做什么限制。 Jinja2使用的语法与django模板使用的相同,但增加了许多增强功能。我知道这听起来像是一个很小的问题,但事实上我敢打赌,你总是发现自己在Django中与默认的模板系统对抗,所以它确实是值得的,我相信它从长远来看,这会让你的工作效率更高。)

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

神社没有一个周期的标签,这对循环周期方法:

{% 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() %} 
+2

对于这样一个小问题,这是一个很大的转变(伴随着一些主要的复杂问题,如第三方或contrib应用程序)。 -1 – 2009-01-20 02:31:35

+3

提出的好点。问题是,我敢打赌,人们总是发现自己与Django模板系统发生冲突,这不仅仅是这个小问题,还有一个问题,那就是一堆烦恼。 – hasen 2009-01-20 03:34:01

+0

感谢您的建议和文章; Django的模板化方法让我感到受到限制,并且受到它的bug的困扰。但是Django总体上很甜美。 – 2009-01-20 06:58:41

-5

有一种使用迭代器在服务器端执行的方法,该迭代器不会同时复制所有条目:

import itertools 
return render_to_response('template.html', 
    { 
    "flattened_entries": itertools.chain(*(blog.entries for blog in blogs)), 
    }) 
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 %}