111 votes

Jinja2 : Modifier la valeur d'une variable à l'intérieur d'une boucle

Je veux changer la valeur de la variable déclarée en dehors de la boucle dans une boucle. Mais toujours changeant, il garde la valeur initiale en dehors de la boucle.

 {% set foo = False %}

{% for item in items %}
  {% set foo = True %}
  {% if foo %} Ok(1)! {% endif %}
{% endfor %}

{% if foo %} Ok(2)! {% endif %}

Cela donne :

 Ok(1)!

Donc la seule (mauvaise) solution trouvée jusqu'à présent était celle-ci :

 {% set foo = [] %}

{% for item in items %}
  {% if foo.append(True) %} {% endif %}
  {% if foo %} Ok(1)! {% endif %}
{% endfor %}

{% if foo %} Ok(2)! {% endif %}

Cela donne :

 Ok(1)!
Ok(2)!

Mais, c'est très moche ! Existe-t-il une autre solution plus élégante ?

95voto

Pashka Points 106

Essayez également une approche basée sur un dictionnaire. Ça a l'air moins moche.

 {% set vars = {'foo': False} %}

{% for item in items %}
  {% if vars.update({'foo': True}) %} {% endif %}
  {% if vars.foo %} Ok(1)! {% endif %}
{% endfor %}

{% if vars.foo %} Ok(2)! {% endif %}

Cela donne également :

 Ok(1)!
Ok(2)!

83voto

Omer Points 660

comme indiqué dans la documentation :

Veuillez noter que les affectations en boucles seront effacées à la fin de l'itération et ne peut pas survivre à la portée de la boucle.

mais à partir de la version 2.10, vous pouvez utiliser des espaces de noms :

     {% set ns = namespace(foo=false) %}      
    {% for item in items %}
      {% set ns.foo = True %}
      {% if ns.foo %} Ok(1)! {% endif %}
    {% endfor %}

    {% if ns.foo %} Ok(2)! {% endif %}

0voto

Daniel F. Points 836

Vous pouvez le faire pour nettoyer le code du modèle

 {% for item in items %}
  {{ set_foo_is_true(local_vars) }}
  {% if local_vars.foo %} Ok(1)! {% endif %}
{% endfor %}
{% if local_vars.foo %} Ok(2)! {% endif %}

Et dans l'utilisation du code serveur

 items = ['item1', 'item2', 'item3']
#---------------------------------------------
local_vars = { 'foo': False }
def set_foo_is_true(local_vars):
  local_vars['foo'] = True
  return ''
env.globals['set_foo_is_true'] = set_foo_is_true    
#---------------------------------------------
return env.get_template('template.html').render(items=items, local_vars=local_vars)

Cela pourrait être généralisé à ce qui suit

 {{ set_local_var(local_vars, "foo", False) }}
{% for item in items %}
  {{ set_local_var(local_vars, "foo", True) }}
  {% if local_vars.foo %} Ok(1)! {% endif %}
{% endfor %}
{% if local_vars.foo %} Ok(2)! {% endif %}

Et dans l'utilisation du code serveur

 items = ['item1', 'item2', 'item3']
#---------------------------------------------
local_vars = { 'foo': False }
def set_local_var(local_vars, name, value):
  local_vars[name] = value
  return ''
env.globals['set_local_var'] = set_local_var
#---------------------------------------------
return env.get_template('template.html').render(items=items, local_vars=local_vars)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X