如何在django中使用forloop计数器而不重置

时间:2013-05-08 04:39:33

标签: python django

我有这段代码

{% for d in list1 %}
    {% for o in d.list2 %}
          <tr>
            <td>{{ forloop.counter}} </td>
            <td>{{ o.name}}</td>
          </tr>
    {% endfor  %}
{% endfor %}

在父循环更改后,计数器正在重置。

有没有办法让计数器不为每个list1循环重置。我想列出list1中所有d的list2中的所有项目,从0 - 10开始

1 个答案:

答案 0 :(得分:7)

正如您所发现的,

forloop.counter仅指内循环的计数器。您可以使用forloop.parentloop.counter访问外部循环的计数器,这将有所帮助。

但是,如果你有这样的数据:

list1 = [
    {'list2': [
        {'name': 'd1 o1'},
        {'name': 'd1 o2'}]},
    {'list2': [
        {'name': 'd2 o1'},
        {'name': 'd2 o2'},
        {'name': 'd2 o3'}]},
    {'list2': [
        {'name': 'd3 o1'},
        {'name': 'd3 o2'}]}
]

并且您想要产生如下输出:

<tr><td>1 </td><td> d1 o1 </td></tr>
<tr><td>2 </td><td> d1 o2 </td></tr>
<tr><td>3 </td><td> d2 o1 </td></tr>
<tr><td>4 </td><td> d2 o2 </td></tr>
<tr><td>5 </td><td> d2 o3 </td></tr>
<tr><td>6 </td><td> d3 o1 </td></tr>
<tr><td>7 </td><td> d3 o2 </td></tr>

只是能够访问父循环是不够的。为此,您有两种选择:

  • 按照Rohan在评论中的建议,或
  • 来整理列表
  • 创建一个可用作计数器的新模板标记。

展平列表是最简单的选择。在您的视图代码中,如果您重新构建数据:

flat_list = list({'d': d, 'o': o} for d in list1 for o in d['list2'])

然后您可以像这样打印列表:

{% for i in flat_list %}
      <tr>
        <td>{{ forloop.counter}} </td>
        <td>{{ i.o.name}}</td>
      </tr>
{% endfor  %}

但是,这可能无法实现,具体取决于您的数据。如果这是不可能的,并且列表不能明智地展平,则必须创建一个新的计数器模板标签,其行为如下:

{% load counter_tags %}
{% counter_from 1 as counter %}
{% for d in list1 %}
    {% for o in d.list2 %}
          <tr>
            <td>{{ counter }} </td>
            <td>{{ o.name}}</td>
          </tr>
    {% endfor  %}
{% endfor %}

将以下内容放在templatetags/counter_tags.py文件中:

import itertools


class Counter(object):
    def __init__(self, start, step=1):
        self.count = itertools.count(start, step)

    def next(self):
        return self.count.next()

    def __iter__(self):
        return self

    def __unicode__(self):
        return unicode(self.next())


@register.assignment_tag
def counter_from(start, step=1):
    return Counter(int(start), int(step))

你的模板中有一个独立于循环的计数器!