Использование значения forloop.counter в качестве индекса списка в шаблоне Django - PullRequest
16 голосов
/ 23 марта 2010

в моем приложении Django 1.1.1 у меня есть функция в представлении, которая возвращает его шаблону диапазон чисел и список списков элементов, например:

...  
data=[[item1 , item2, item3], [item4, item5, item6], [item7, item8, item9]]  
return render_to_response('page.html', {'data':data, 'cycle':range(0,len(data)-1])

Внутри шаблона у меня есть внешний цикл for, который также содержит еще один цикл for для отображения на выходе содержимого внутренних списков данных таким образом

...  
{% for page in cycle %}   
...   
< table >   
{% for item in data.forloop.counter0 %}  
< tr >< td >{{item.a}} < /td > < td > {{item.b}} ... < /td > < /tr >  
...  
< /table >  
{% endfor %}  
{% if not forloop.last %}  
< div class="page_break_div" >  
{% endif %}  
{% endfor %}  
... 

Но движок шаблонов Django не работает со значением forloop.counter0 в качестве индекса для списка (вместо этого он работает, если вручную ввести числовое значение в качестве индекса). Есть ли способ, чтобы цикл списка работал с внешним значением forloop.counter0? Заранее спасибо за помощь:)

Ответы [ 4 ]

17 голосов
/ 28 октября 2010

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

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

{% for list1item in list1 %}
   {% for list2item in list2 %}
      {% if forloop.counter == forloop.parentloop.counter %}
          {{ list1item }} {{ list2item }}
      {% endif %}
   {% endfor %}
{% endfor %}
12 голосов
/ 23 марта 2010

Нельзя использовать переменные для имен атрибутов, ключей словаря или индексов списка.

Также range(0,len(data)-1] не является допустимым питоном. Это должно быть range(len(data)).

Вам, вероятно, не нужно cycle. Может быть, то, что вы хотите, это:

{% for itemlist in data %}
    ...
    <table>
        {% for item in itemlist %}
        <tr>
          <td>{{ item.a }}</td>
          <td>{{ item.b }} ... </td>
        </tr>
        ...
        {% endfor %}
    </table>
    {% if not forloop.last %}
        <div class="page_break_div">
    {% endif %}
{% endfor %}
3 голосов
/ 01 июля 2012

Я хотел, чтобы в моей таблице были чередующиеся цвета, используя таблицу стилей, передавая список переключаемых значений True / False. Я нашел это действительно расстраивающим. В конце я создал список элементов словаря с теми же ключами, что и у полей в таблице, плюс еще один с переключаемым значением true / false.

def jobListView(request):
    # django does not allow you to append stuff to the job identity, neither
    # will it allow forloop.counter to index another list. The only solution
    # is to have the toggle embedded in a dictionary along with
    # every field from the job
    j                   = job.objects.order_by('-priority')
    # have a toggling true/false list for alternating colours in the table
    theTog              = True
    jobList             = [] 
    for i in j:
        myJob           = {}
        myJob['id']     = i.id
        myJob['duty']   = i.duty
        myJob['updated'] = i.updated
        myJob['priority'] = i.priority
        myJob['description'] = i.description
        myJob['toggle'] = theTog
        jobList.append(myJob)
        theTog          = not(theTog)
    # next i

    return render_to_response('index.html', locals())
# end jobDetaiView

и мой шаблон

{% if jobList %}
    <table border="1"><tr>
    <th>Job ID</th><th>Duty</th><th>Updated</th><th>Priority</th><th>Description</th>
    </tr>

    {% for myJob in jobList %}

        <!-- only show jobs that are not closed and have a positive priority. -->
        {% if myJob.priority and not myJob.closeDate %}
            <!-- alternate colours with the classes defined in the style sheet -->
            {% if myJob.toggle %}
                <tr class=d1> 
            {% else %}
                <tr class=d0>
            {% endif %}

            <td><a href="/jobs/{{ myJob.id }}/">{{ myJob.id }}</td><td>{{ myJob.duty }}</td> 
            <td>{{ myJob.updated }}</td><td>{{ myJob.priority }}</td>
            <td class=middle>{{ myJob.description }}</td>
            </tr>
        {% endif %}
    {% endfor %}
    </ul>
{% else %}
    <p>No jobs are in the system.</p>
{% endif %}
0 голосов
/ 02 марта 2018

Использовать forloop.last - True, если это последний раз в цикле:

{% if forloop.last %}
{% endif %}

С Встроенные шаблоны тегов и фильтров

...