如何在Jinja模板的for循环中增加一个变量?

119
我想要做这样的事情:
变量p来自于test.py,它是一个列表['a','b','c','d']。
{% for i in p %}
{{variable++}}
{{variable}}

输出结果为:
1 2 3 4

8个回答

204

您可以使用 loop.index

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

请查看模板设计者文档

在更近的版本中,由于作用域规则,以下代码将不会起作用:

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

6
使用这个答案来解决作用域问题。 - faruk13
@faruk13,你的提示解决了我的问题 :) 这个答案也起作用了。 - Tushar Niras
@zeekay请将此处“由于作用域规则,以下内容不起作用:”标记为粗体,几乎生气了。 - Azhar Uddin Sheikh
请注意,loop.index从1开始而不是0。 - Jabba
请注意,loop.index 从1开始而不是0。 - undefined

123

2.10版本之后,为了解决范围问题,您可以尝试像这样做:

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

5
我遇到了错误:在 /listing/ 上,模板语法错误:第 145 行上存在无效的块标签 'set',期望为 'endblock'。您是否忘记注册或加载此标签?代码如下: {% set count = namespace(value=0) %}您有什么想法是导致这个错误的原因吗? - Andrew
如果你和我一样在使用Django,需要注意的是Django不支持set。我最终通过在Django模型中定义一个函数来进行计算来解决了这个问题,正如这个答案所提到的:https://dev59.com/mlkT5IYBdhLWcg3wG70_#48158461。 - cylim

65

正如Jeroen所说,存在作用域问题:如果在循环外设置'count',则无法在循环内修改它。

您可以通过使用对象而不是标量来解决此问题:

{% set count = [1] %}

现在你可以在for循环或者%include%中操作计数。下面是我如何增加计数的方法(是有些笨拙,但也没办法):

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

或者...
{% set count = [] %}
{% for something-that-loops %}
   {% set __ = count.append(1) %} 
   <div> Lorem ipsum meepzip dolor...
   {{ count|length }}
   </div>
{% endfor %}

(来自@eyettea和@PYB的评论)


Peter Hollingsworth。非常感谢你提供的信息,对我帮助很大。 - mthecreator
7
另一个我认为更加简洁的解决方案是初始化一个空列表 {% set count = [] %},在每个循环中向列表添加一个项目 {% set __ = index.append(1) %},并使用长度来显示索引 index|length - eyettea
1
另外,您可以像这样使用do语句{% do index.append(1) %}。但是您必须添加在此处描述的扩展extention - AstraSerg
3
更正 @eyettea 的简洁解决方案: 我认为更简洁的另一个解决方案是初始化一个空列表 {% set count = [ ] %},在每个循环中添加一个项目 {% set __ = count.append(1) %},然后使用长度来显示计数 count|length - PYB

20

这是我的解决方案:

将所有计数器放入字典中:

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

优雅的解决方案,解决了一个混乱的问题。谢谢! - Sevak Avakians
非常好!我需要在两个嵌套的for循环中滚动累积计数索引。这对于此用例非常有效。 - jxramos
同意,这非常优雅! - Sidharrth Nagappan

5

如果任何人想在循环中添加一个值,那么可以使用以下方法,它百分之百可行:

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

{{ftotal.total}}

输出结果为 5


优秀的解决方案,但你应该为初学者解释得更详细一些。 - Sadique Khan

2

我也曾遇到这个问题。我想在jinja中根据计数器更改div类。我很惊讶pythonic方式不起作用。以下代码在每次迭代时重置了我的计数器,所以我只有红色类。

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

2

我来搜索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/


3
那是Django模板引擎,OP要求使用jinja2。 - Jahid
1
谢谢,这对我很有帮助! - Zohab Ali

0

为了更好地解决这个问题。 Jinja2变量的行为与传统脚本语言不同,您无法在for循环中修改变量。因此,为了绕过这种行为,您可以使用字典,因为您可以更改字典的值。

**{% set margin={"margin_value":0} %}** 
{% for lang in language %}
<ul>
    <li style="margin-right: {{ margin.margin_value}}px">{{ lang }}</li>
</ul>
**{% if margin.update({"margin_value":margin.margin_value + 2}) %} 
{% endif %}** 
{% endfor %}

在上述代码中,字典的值正在被修改。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接