2013-05-08 5 views
1

У меня этот кодКак можно использовать счетчик forloop в Джанго без сброса

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

Счетчик перезагрузка после изменения родительского цикла.

Есть ли способ сделать счетчик не сброшен для каждого цикла list1. Я хочу перечислить все элементы в списке2 для всех d в списке1, начиная с 0 - 10

+2

Вам нужно будет создать плоский список в представлении и передать его шаблону, а не вложенному списку. – Rohan

+0

еще не пытался, но, вероятно, вы могли видеть 'with': https://docs.djangoproject.com/en/dev/ref/templates/builtins/#with – yuwang

+0

во внешнем цикле,' {% with counter = forloop.counter%} 'while во внутреннем цикле,' {{counter}} ' – yuwang

ответ

6

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> 

Просто быть в состоянии получить доступ к родительский цикл не является достаточно хорошим. Для этого у вас есть два варианта:

  • Свести списки, как это было предложено Рохана в комментариях, или
  • Создайте новый тег шаблона, который может выступать в качестве противовеса.

Сглаживание списка является самым простым вариантом. С вашей точки зрения кода, если вы реструктурировать свои данные следующим образом:

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

И у вас в ваших шаблонах есть независимый от цикла счетчик!

Смежные вопросы