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>
親ループにアクセスできるだけでは十分ではありません。これには、次の 2 つのオプションがあります。
- コメントで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))
そして、テンプレートにループに依存しないカウンターがあります!