2
votes

jinja2 - boucle dans un dictionnaire

Je suis nouveau avec Jinja2 peut-être ma question est noobie mais je ne peux pas la comprendre.

J'utilise donc Jinja2 pour un Ansible code> tâche comme modèle pour créer un fichier, j'ai un dictionnaire défini dans le fichier de la variable par défaut comme:

{% for item in test123.values() -%}
{{ item.name }}="{{ item.number }}"
{%- endfor %} 
{% for item in test123.testB.values() -%}
    {{ item.name }}="{{ item.number }}"
{%- endfor %} 

Maintenant dans mon fichier Jinja2 , Je veux parcourir ce dictionnaire et imprimer tout ce qui est défini dans le dictionnaire.

J'ai essayé plusieurs exemples mais rien ne fait la bonne chose.

Par exemple:

test123:
  testA:
    name: test1
    number: 1
    path: /tmp/test.txt
  testB:
    name: test2
    number: 2
    path: /tmp/test.txt

Message d'erreur:

fatal: [serveur de tests]: ECHEC! => {"changé": faux, "msg": "AnsibleUndefinedVariable: 'objet ansible.parsing.yaml.objects.AnsibleUnicode' n'a pas d'attribut 'nom' "}

J'ai pensé que la meilleure chose serait peut-être de créer une boucle while pour cela et de tout imprimer, mais comme dans Jinja2 il n'y a pas de boucle while, je ne sais pas comment fais le.

Quelqu'un a-t-il une idée de comment y parvenir? Donc, encore une fois, l'objectif est de tout imprimer du dictionnaire dans le fichier Jinja2 .

Merci d'avance


4 commentaires

Ce n'est pas un dictionnaire Python ... je ne suis pas sûr d'Ansible.


Quelle version de Python sur l'hôte cible?


@amanb J'ai utilisé ce manuel pour créer un dictionnaire en ansible: docs.ansible .com / ansible / latest / plugins / lookup / dict.html (dans l'exemple en haut, vous pouvez voir l'exemple) donc jinja2 ne peut rien faire avec ce dictionnaire?


La version de @ozlevka python sur l'hôte cible est: Python 2.7.5


3 Réponses :


0
votes

Ce n'est pas un dictionnaire python. cependant si vous avez une liste de dictés:

{% for item in test123 %}
    {{ item.name }}="{{ item.number }}"
{% endfor %}

ce code jinja devrait fonctionner:

test123 = [
    {'name':'test1', 'number': 1, 'path': '/tmp/test.txt'},
    {'name':'test2', 'number': 2, 'path': '/tmp/test.txt'},
    ]

bien sûr, vous devez passer ce dict à votre fonction de rendu (vous ne publiez pas le code de votre contrôleur). Aucune idée si cela s'applique bien à ansible.


2 commentaires

Salut, Merci pour votre réponse, malheureusement, cela ne fonctionne pas comme prévu au moins dans ansible ... J'ai essayé quelque chose comme ça `test_dict: [{'name': 'test1', 'number': '1', 'path': '/tmp/test.txt'}] `et je l'ai fait fonctionner, mais ce n'est pas vraiment la solution que j'ai recherchée car je veux avoir plusieurs 'clés' avec d'autres valeurs et l'utiliser dans le fichier de modèle à une position spécifique si vous comprenez ce que je veux dire :)


je pense que vous cherchez une liste de dictionnaires. Je modifie ma réponse



0
votes

Une option serait d'utiliser dict2items filtre. Le modèle ci-dessous

{'value': {u'path': u'/tmp/test.txt', u'name': u'test1', u'number': 1}, 'key': u'testA'}
{'value': {u'path': u'/tmp/test.txt', u'name': u'test2', u'number': 2}, 'key': u'testB'}

key: testA
value.number: 1
value.name: test1
value.path: /tmp/test.txt

key: testB
value.number: 2
value.name: test2
value.path: /tmp/test.txt

donne

{% for item in test123|dict2items %}                                                
{{ item }}                                                                          
{% endfor %}

{% for item in test123|dict2items %}
key: {{ item.key }}
value.number: {{ item.value.number }}
value.name: {{ item.value.name }}
value.path: {{ item.value.path }}

{% endfor %}


2 commentaires

Salut, merci pour votre réponse. Je l'ai testé et j'ai obtenu les valeurs comme vous l'avez écrit dans votre exemple mais je dois maintenant ajouter une valeur spécifique dans une zone spécifique par exemple: `` nom de l'utilisateur: key.testA.name '' `` Donc je ferais quelque chose comme: `` {% for item in test123 | dict2items%} nom de l'utilisateur: {{test123.testA [name] .item}} {% endfor%} `` Mais cela ne fonctionne pas donc je pense la syntaxe est fausse, non? Merci d'avance.


Voir la réponse mise à jour. Si vous avez des questions, suivez Comment créer un exemple minimal, complet et vérifiable et modifiez votre question.



3
votes

Ce qui suit créerait une sortie contenant tous les noms d'utilisateurs

name of the user: test1
name of the user: test2

Format de sortie:

{% for item in test123.values() %}
name of the user: {{ item.name }}
{% endfor %}

Si vous avez besoin de quelque chose dans format spécifique me faire savoir le résultat souhaité


2 commentaires

Fonctionne comme prévu :) donc le .values ​​() appelle toutes les valeurs dans le droit dict?


Oui. alors vous pouvez accéder aux sous-éléments en utilisant le item.name et {{}} est utilisé pour le remplacement de variable dans jinja2