Как увеличить переменную в цикле for в шаблоне jinja?


83

Я бы хотел сделать что-то вроде:

переменная p взята из test.py, которая представляет собой список ['a', 'b', 'c', 'd']

{% for i in p %}
{{variable++}}
{{variable}}

результат вывод:
1 2 3 4

Ответы:


157

Вы можете использовать loop.index:

{% for i in p %}
  {{ loop.index }}
{% endfor %}

Проверьте документацию дизайнера шаблонов .

В более поздних версиях из-за правил области действия следующее не работает:

{% set count = 1 %}
{% for i in p %}
  {{ count }}
  {% set count = count + 1 %}
{% endfor %}

Используйте этот ответ, чтобы решить проблему с
областью

68

После 2.10, чтобы решить проблему с областью видимости, вы можете сделать что-то вроде этого:

{% set count = namespace(value=0) %}
{% for i in p %}
  {{ count.value }}
  {% set count.value = count.value + 1 %}
{% endfor %}

1
Я получаю сообщение об ошибке: TemplateSyntaxError в / листинг / Недопустимый тег блока в строке 145: «set», ожидаемый «endblock». Вы забыли зарегистрировать или загрузить этот тег? Вкл: {% set count = namespace (value = 0)%} Есть идеи о причине этого?
Эндрю

56

Как говорит Йерун, существуют проблемы с областью видимости: если вы установите «count» вне цикла, вы не сможете изменить его внутри цикла.

Вы можете победить это поведение, используя объект, а не скаляр для count:

{% set count = [1] %}

Теперь вы можете управлять счетчиком внутри цикла forloop или даже% include%. Вот как я увеличиваю счетчик (да, это глупо, но да ладно):

{% if count.append(count.pop() + 1) %}{% endif %} {# increment count by 1 #}

Питер Холлингсворт. Большое спасибо за эту информацию, мне очень помогли.
mthecreator

6
Другое решение, которое немного чище imo, - это инициализировать пустой список {% set count = [] %}, добавлять элемент в список в каждом цикле {% set __ = index.append(1) %}и использовать длину для отображения индекса index|length.
eyettea 06

1
Кроме того, вы можете использовать такой оператор do,{% do index.append(1) %} но вы должны добавить расширение, описанное здесь
AstraSerg

2
Исправление чистого решения @eyettea: еще одно решение, которое, по-моему, немного чище, - это инициализировать пустой список {% set count = [ ] %}, добавить элемент в список в каждом цикле {% set __ = count.append(1) %}и использовать длину для отображения счетчикаcount|length
PYB 02

14

Вот мое решение:

Поместите все счетчики в словарь:

{% set counter = {
    'counter1': 0,
    'counter2': 0,
    'etc': 0,
    } %}

Определите макрос, чтобы легко их увеличивать:

{% macro increment(dct, key, inc=1)%}
    {% if dct.update({key: dct[key] + inc}) %} {% endif %}
{% endmacro %}

Теперь, когда вы хотите увеличить счетчик counter1, просто выполните:

{{ increment(counter, 'counter1') }}

Элегантное решение запутанной проблемы. Спасибо!
SevakPrime

Очень хорошо! Мне нужен был кумулятивный счетный индекс, перекатывающийся по двум вложенным циклам for. Это отлично подходит для этого варианта использования.
jxramos

2

Я тоже боролся с этим поведением. Я хотел изменить класс div в jinja на основе счетчика. Я был удивлен, что питонический способ не работал. Следующий код сбрасывал мой счетчик на каждой итерации, поэтому у меня был только красный класс.

{% if sloupec3: %}
    {% set counter = 1 %}
    {% for row in sloupec3: %}
        {% if counter == 3 %}
            {% set counter = 1 %}        
        {% endif %} 

        {% if  counter == 1: %}
           <div class="red"> some red div </div>
        {% endif %} 

        {% if counter == 2: %}
           <div class="gray"> some gray div </div>
        {% endif %} 

        {% set counter = counter + 1 %} 

    {% endfor %}

{% endif %}

Я использовал loop.index вот так, и он работает:

{% if sloupec3: %}

    {% for row in sloupec3: %} 

        {% if  loop.index % 2 == 1: %}
           <div class="red"> some red div </div>
        {% endif %} 

        {% if loop.index % 2 == 0: %}
           <div class="gray"> some gray div </div>
        {% endif %}  

    {% endfor %}

{% endif %}

1

если кто-то хочет добавить значение внутри цикла, вы можете использовать его на 100%

{% set ftotal= {'total': 0} %} 
{%- for pe in payment_entry -%}
    {% if ftotal.update({'total': ftotal.total + 5}) %}{% endif %} 
{%- endfor -%}

{{ftotal.total}}

output = 5


0

Пришел искать способ сделать это Django и нашел этот пост. Может быть, кому-то еще нужно решение django, пришедшее сюда.

{% for item in item_list %}
    {{ forloop.counter }} {# starting index 1 #}
    {{ forloop.counter0 }} {# starting index 0 #}

    {# do your stuff #}
{% endfor %}

Подробности здесь: https://docs.djangoproject.com/en/1.11/ref/templates/builtins/


2
Это шаблонизатор Django, OP попросил jinja2
Джахид

Спасибо, что помогли мне!
Зохаб Али
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.