Setting variable in Jinja for loop doesn't persist between iterations

后端 未结 3 1019
既然无缘
既然无缘 2021-01-19 16:27

I want to loop over a list of objects and count how many objects meet a requirement. I based my code off other examples I\'d found, but it doesn\'t work, the count is always

3条回答
  •  感情败类
    2021-01-19 17:01

    Jinja 2.10 introduces the namespace object to handle assignment and comparison in loops.

    {% set ns = namespace(beds=0) %}
    {% for room in house %}
        {% if room.has_bed %}
            {% set ns.beds = ns.beds + 1 %}
        {% endif %}
    {% endfor %}
    {{ house.address }} has {{ ns.beds }} beds.
    

    Normally, set does not handle attributes, which is why the old answers mutate objects with methods instead. namespace has been special cased so setting attributes does work.

    The reason the original counter didn't work is because of Jinja's scope rules. Unlike Python, most blocks are new scopes. set always defines a local variable, except in this new special case of namespace.attribute.


    In this specific case, you can accomplish what you want with filters.

    {% set beds = house.rooms|selectattr('has_bed')|length %}
    {{ house.address }} has {{ beds }} beds.
    

    However, there are cases where storing information across scopes is needed. For example, if you wanted to output some information in addition to incrementing the counter, it would make sense to use a namespace.

提交回复
热议问题