Wie inkrementiere ich eine Variable in einer for-Schleife in einer Jinja-Vorlage?

80

Ich möchte etwas tun wie:

Die Variable p stammt aus test.py und ist eine Liste ['a', 'b', 'c', 'd'].

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

Ergebnisausgabe ist:
1 2 3 4

user422100
quelle

Antworten:

155

Sie könnten verwenden loop.index:

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

Überprüfen Sie die Dokumentation des Vorlagendesigners .

In neueren Versionen würde aufgrund von Gültigkeitsregeln Folgendes nicht funktionieren:

{% set count = 1 %}
{% for i in p %}
  {{ count }}
  {% set count = count + 1 %}
{% endfor %}
Zeekay
quelle
Verwenden Sie diese Antwort, um das Scoping-Problem zu lösen
faruk13
65

Nach 2.10 können Sie Folgendes tun, um das Scope-Problem zu lösen:

{% set count = namespace(value=0) %}
{% for i in p %}
  {{ count.value }}
  {% set count.value = count.value + 1 %}
{% endfor %}
Patrick José Pereira
quelle
Ich erhalte die Fehlermeldung: TemplateSyntaxError at / Listing / Ungültiges Block-Tag in Zeile 145: 'set', erwarteter 'Endblock'. Haben Sie vergessen, dieses Tag zu registrieren oder zu laden? Ein: {% set count = Namespace (Wert = 0)%} Haben Sie eine Vorstellung von der Ursache dafür?
Andrew
55

Wie Jeroen sagt, gibt es Probleme mit dem Umfang: Wenn Sie 'count' außerhalb der Schleife festlegen, können Sie es nicht innerhalb der Schleife ändern.

Sie können dieses Verhalten umgehen, indem Sie ein Objekt anstelle eines Skalars für 'count' verwenden:

{% set count = [1] %}

Sie können jetzt die Anzahl innerhalb eines Forloops oder sogar ein% include% manipulieren. So erhöhe ich die Anzahl (ja, es ist klobig, aber na ja):

{% if count.append(count.pop() + 1) %}{% endif %} {# increment count by 1 #}
Peter Hollingsworth
quelle
Peter Hollingsworth. Vielen Dank für diese Info, hat mir sehr geholfen.
Schöpfer
6
Eine andere Lösung, die imo etwas sauberer ist, besteht darin, eine leere Liste zu initialisieren {% set count = [] %}, der Liste in jeder Schleife ein Element hinzuzufügen {% set __ = index.append(1) %}und den Index anhand der Länge anzuzeigen index|length.
Eyettea
1
Sie können auch eine do- Anweisung wie diese verwenden. {% do index.append(1) %} Sie müssen jedoch die hier
AstraSerg
2
Korrigieren der sauberen Lösung von @eyettea: Eine andere Lösung, die imo etwas sauberer ist, besteht darin, eine leere Liste zu initialisieren {% set count = [ ] %}, der Liste in jeder Schleife ein Element hinzuzufügen {% set __ = count.append(1) %}und die Anzahl zu verwenden, um die Anzahl anzuzeigencount|length
PYB
13

Hier ist meine Lösung:

Fügen Sie alle Zähler in ein Wörterbuch ein:

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

Definieren Sie ein Makro, um sie einfach zu erhöhen:

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

Wenn Sie jetzt den Zähler 'counter1' erhöhen möchten, gehen Sie einfach wie folgt vor:

{{ increment(counter, 'counter1') }}
Jahid
quelle
Elegante Lösung für ein unordentliches Problem. Vielen Dank!
SevakPrime
Sehr gut! Ich brauchte einen kumulativen Zählindex, der über zwei verschachtelte for-Schleifen rollte. Dies funktioniert hervorragend für diesen Anwendungsfall.
Jxramos
2

Ich hatte auch mit diesem Verhalten zu kämpfen. Ich wollte die Div-Klasse in Jinja basierend auf dem Zähler ändern. Ich war überrascht, dass der pythonische Weg nicht funktionierte. Der folgende Code setzte meinen Zähler bei jeder Iteration zurück, sodass ich nur eine rote Klasse hatte.

{% 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 %}

Ich habe loop.index so verwendet und es funktioniert:

{% 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 %}
TomRavn
quelle
1

Kam auf der Suche nach Djangos Art dies zu tun und fand diesen Beitrag. Vielleicht braucht jemand anderes die Django-Lösung, der hierher kommt.

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

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

Lesen Sie hier mehr: https://docs.djangoproject.com/de/1.11/ref/templates/builtins/

Smoking Joe
quelle
2
Das ist Django Template Engine, OP fragte nach jinja2
Jahid
Danke, das hat mir geholfen!
Zohab Ali
0

Wenn jemand einen Wert innerhalb der Schleife hinzufügen möchte, können Sie diesen zu 100% verwenden

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

{{ftotal.total}}

Ausgabe = 5

Pratik Soni
quelle