2008-11-07 5 views
44

En mi views.py, estoy construyendo una lista de dos tuplas, donde el segundo elemento de la tupla es otra lista, como esta:Django - Cómo hacer tuple desempacando en un bucle de plantilla 'for'

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

en la antigua llanura de Python, pude iteración la lista como esta:

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

me parece que no puede hacer lo mismo en mi plantilla de Django:

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

me sale este error de Django:

detectó una excepción al intentar mostrar: Código postal argumento # 2 debe apoyar iteración

Por supuesto, hay algo de marcado HTML en la plantilla, no imprimir declaraciones. ¿No se admite el desempaquetado de tuplas en el lenguaje de plantillas de Django? ¿O estoy yendo sobre esto de la manera incorrecta? Todo lo que intento hacer es mostrar una jerarquía simple de objetos: hay varios tipos de productos, cada uno con varios productos (en models.py, Product tiene una clave externa para Product_type, una relación simple de uno a muchos).

Obviamente, soy bastante nuevo en Django, por lo que cualquier contribución sería apreciada.

+2

Usted habla de tuplas, pero su pregunta contiene solo listas Son cosas diferentes en Python. –

+0

En realidad, no tiene dos tuplas. Mire cuidadosamente su lista, tiene 4 elementos de la lista. Como se ha señalado Jonny Buchanan, que tiene que hacer esto: [[Product_Type_1, [product_1, product_2],], [Product_Type_2, [product_3, product_4],],] para obtener una versión lista de-dos tuplas. – MontyThreeCard

Respuesta

53

que sería mejor si construye sus datos como {Nota de la ('y ')' se puede cambiar por '[' y ']' repectively, siendo uno de tuplas, uno para las listas}

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

y tienen la plantilla de hacer esto:

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

la forma tuplas/listas se descomprimen en los bucles se basa en el artículo devuelto por el iterador de la lista. cada iteración solo se devolvió un elemento. la primera vez alrededor del bucle, Product_Type_1, el segundo de su lista de productos ...

+1

es decir, creía que estaba compilando una lista de dos tuplas, pero olvidó la parte de tupla; tenga en cuenta los paréntesis adicionales que rodean los pares de tipo de producto/lista de productos en la respuesta de Cipher –

+0

Esto no funciona con versiones anteriores de Django (como la utilizada en el GAE). Use la respuesta de Ashwin Rao si obtiene este error: "las declaraciones 'para' con cinco palabras deben terminar en 'invertido'" –

2

acaba de enviar la plantilla de una lista de tipos de productos y hacer algo como:

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

Ha sido un poco de tiempo, así que no puedo recordar exactamente lo que la sintaxis es, hágamelo saber si funciona. Verifique el documentation.

+0

+1: no sobre procesar en la vista –

+0

Chris Lawlor no ha explicado cómo terminó con la estructura de datos que tiene (que en realidad no es una lista de dos tuplas), pero este enfoque sugerido resultaría en N + 1 consultas para mostrar la lista de productos. –

+0

Aquí hay dragones. Con esta sugerencia, realiza un viaje por separado a la base de datos para cada tipo de producto. Sospecho que minimizar la carga de la base de datos es probablemente la motivación detrás del uso de tuplas en primer lugar. – btubbs

5

Debe utilizado de esta manera:

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

No se olvide de los elementos variables en los datos del diccionario

+0

Finalmente, la respuesta que estaba buscando. ¡Gracias! – Teekin

57

Otra forma es la siguiente.

Si uno tiene una lista de tuplas dicen

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

entonces uno puede descomprimir esta lista en el archivo de plantilla de la siguiente manera. En mi caso tenía una lista de tuplas que contenían la URL, el título y el resumen de un documento.

{\% for item in mylst \%}  
    {{ item.0 }} {{ item.1}} {{ item.2 }}  
{\% endfor \%} 
+0

Esto es exactamente lo que estaba buscando, gracias. – mlsteeves

+4

'.0' ... no es intuitivo en absoluto. –

+0

El truco de @iuliux es recordar que el lenguaje de plantilla hace que '.' signifique cualquier cosa, desde el acceso variable a la suscripción, pasando por la invocación del método, todo con la misma sintaxis ... Aún estoy de acuerdo, aunque :) – mccc

1

Si tiene un número fijo en sus tuplas, puede usar la indexación.Que necesitaba para mezclar un diccionario y los valores fueron de tuplas, así que hice esto:

En la vista:

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

En la plantilla:

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