Skip to main content
 首页 » 编程设计

python之我如何在不重置的情况下在django中使用forloop计数器

2025年05月04日14jpfss

我有这个代码

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

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

有什么方法可以使每个 list1 循环的计数器不重置。我想列出 list2 中所有 d 中的所有项目,从 0 - 10

开始

请您参考如下方法:

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 在评论中的建议,将列表展平,或者
  • 创建一个可以充当计数器的新模板标签。

扁平化列表是最简单的选择。在您的 View 代码中,如果您像这样重组数据:

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)) 

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