web-dev-qa-db-fra.com

Django - Comment faire le déballage de tuple dans un modèle de boucle 'for')

Dans mon views.py, je construis une liste de deux tuples, où le deuxième élément du tuple est une autre liste, comme ceci:

[ Product_Type_1, [ product_1, product_2 ],
  Product_Type_2, [ product_3, product_4 ]]

En simple vieux Python, je pourrais parcourir la liste comme ceci:

for product_type, products in list:
    print product_type
    for product in products:
        print product

Je n'arrive pas à faire la même chose dans mon modèle Django:

{% for product_type, products in product_list %}
    print product_type
    {% for product in products %}
        print product
    {% endfor %}
{% endfor %}

Je reçois cette erreur de Django:

ne exception a été détectée lors du rendu: l'argument Zip # 2 doit prendre en charge l'itération

Bien sûr, il y a du balisage HTML dans le modèle, pas des instructions d'impression. Le décompactage de tuple n'est-il pas pris en charge dans le langage de modèle Django? Ou est-ce que je me trompe? Tout ce que j'essaie de faire est d'afficher une hiérarchie simple des objets - il existe plusieurs types de produits, chacun avec plusieurs produits (dans models.py, Product a une clé étrangère vers Product_type, une simple relation un-à-plusieurs).

Évidemment, je suis assez nouveau sur Django, donc toute contribution serait appréciée.

55
Chris Lawlor

il serait préférable que vous construisiez vos données comme {notez que les '(' et ')' peuvent être échangés contre '[' et ']' respectivement, un pour les tuples, un pour les listes}

[ (Product_Type_1, ( product_1, product_2 )),
   (Product_Type_2, ( product_3, product_4 )) ]

et demandez au modèle de faire ceci:

{% for product_type, products in product_type_list %}
    {{ product_type }}
    {% for product in products %}
        {{ product }}
    {% endfor %}
{% endfor %}

la façon dont les tuples/listes sont décompressées pour les boucles est basée sur l'élément retourné par l'itérateur de liste. à chaque itération, un seul article a été retourné. la première fois dans la boucle, Product_Type_1, la seconde votre liste de produits ...

63
Jake

Une autre façon est la suivante.

Si l'on a une liste de tuples, dites:

mylst = [(a, b, c), (x, y, z), (l, m, n)]

alors on peut décompresser cette liste dans le fichier modèle de la manière suivante. Dans mon cas, j'avais une liste de tuples qui contenait l'URL, le titre et le résumé d'un document.

{% for item in mylst %}    
     {{ item.0 }} {{ item.1}} {{ item.2 }}    
{% endfor %}
75
Ashwin Rao

Vous devez utiliser cette façon:

{% for product_type, products in product_list.items %}
    print product_type
    {% for product in products %}
        print product
    {% endfor %}
{% endfor %}

N'oubliez pas les éléments variables dans les données du dictionnaire

5
Yasel

Si vous avez un nombre fixe dans vos tuples, vous pouvez simplement utiliser l'indexation. J'avais besoin de mélanger un dictionnaire et les valeurs étaient des tuples, alors j'ai fait ceci:

Dans la vue:

my_dict = {'parrot': ('dead', 'stone'), 'lumberjack': ('sleep_all_night', 'work_all_day')}

Dans le modèle:

<select>
  {% for key, Tuple in my_dict.items %}
    <option value="{{ key }}" important-attr="{{ Tuple.0 }}">{{ Tuple.1 }}</option>
  {% endfor %}
</select>
3
famousfilm

Envoyez simplement au modèle une liste de types de produits et faites quelque chose comme:

{% for product_type in product_type_list %}
    {{ product_type }}
    {% for product in product_type.products.all %}
        {{ product }}
    {% endfor %}
{% endfor %}

Cela fait un petit moment donc je ne me souviens pas exactement de la syntaxe, faites-moi savoir si cela fonctionne. Vérifiez le documentation .

2
Harley Holcombe