2011-09-26 21 views
5

Estoy tratando de obtener el siguiente funcionamiento.Usar para variable de bucle como clave del diccionario en la plantilla de Django

El bucle de recuento debe recorrer todos los valores, y es posible que no haya un usuario asociado a cada recuento, pero el valor de recuento i debe utilizarse en cada bucle para pasar al JavaScript.

parte pitón:

users = {} 
users[1]={} 
users[1][id]=... 
users[1][email]=... 

... 

count=[1,2,3,4,5,6,7,8,9,10] 

Django parte de plantilla:

{% for i in count %} 
do some stuff with the value i using {{i}} which always returns the value, i.e. 1 

email:{% if users.i.email %}'{{users.i.email}}'{% else %}null{% endif%} 
{% endfor %} 

Esto devuelve nada por correo electrónico. Cuando sustituyo el número 1 por i en {% if user.i.email %}, el correo electrónico devuelve la dirección de correo electrónico de los usuarios. Estoy usando los datos en JavaScript, por lo que debe ser implícitamente nulo si no existe. Parece que no logro que Django reconozca la variable i como una variable en lugar del valor i.

usando [] no funciona, ya que genera un error de sintaxis no válida

email:{% if users.[i].email %}'{{users.[i].email}}'{% else %}null{% endif%} 

He intentado usar "with" declaración

{% for i in count %}{% with current_user=users.i %}... 

y luego usando current_user.email, pero regresó nada

También han intentado

{% for i in count %}{% with j=i.value %}... 

en caso de que funcione, y luego intentar usar j, pero el mismo resultado.

He pensado en crear un bucle for interno que pase por encima del objeto del usuario y compruebe si es igual a la clave/valor, pero parece caro y no muy escalable.

¿Alguna idea de cómo puedo forzar a Django a ver i como una variable y usar su valor como índice, o de otra manera evitar esto?

Gracias

Jayd

* Editar:

He probado el extra para bucle, según lo sugerido por Abhi, a continuación.

{% for i in count %} 
    {% for key, current_user in users.items %} 
     do some stuff with the value i using {{i}} which always returns the value, i.e. 1 
     email:{% if i == key and current_user.email %}'{{current_user.email}}'{% else %}null{% endif%} 
    {% endfor %} 
{% endfor %} 

Este tipo de obras, pero ahora se repetirá do some stuff with the value i para cada valor de los usuarios. y si pongo en un caso:

{% for i in count %} 
    {% for key, current_user in users.items %} 
    {% if i == key %} 
     do some stuff with the value i using {{i}} which always returns the value, i.e. 1 
     email:{% if i == key and current_user.email %}'{{current_user.email}}'{% else %}null{% endif%} 
    {% endif%} 
    {% endfor %} 
{% endfor %} 

que ignora los bucles cuando un recuento no tiene un usuario en particular.

La única forma que puedo ver a este respecto es tener el bucle de usuario en cada lugar que deseo usar current_user.

{% for i in count %} 
     do some stuff with the value i using {{i}} which always returns the value, i.e. 1 
     email:{% for key, current_user in users.items %}{% if i == key and current_user.email %}'{{current_user.email}}'{% else %}null{% endif%}{% endfor %} 
{% endfor %} 

Y esto parece muy costoso de hacer. Alguna idea?

Estaba pensando tal vez escribir un filtro que devuelve los valores para los usuarios que utilizan i como la clave:

{% with current_user=users|getuser:i %} 

Pero no sé si esto funcionará o que obtendrá el mismo error, en donde i se pasa como el valor 'i' en lugar de un nombre de variable.

Lo intentaré tanto.

* Editar

Esto no funcionó. El filtro funcionó usando {{}} devolviendo el objeto, pero no funcionó dentro de {% %} .

Gracias por la entrada

+1

¿Por qué utiliza un diccionario para la recogida externa en lugar de una lista? –

+0

¿Por qué usaste el formato ** negrita ** a lo largo de esta pregunta, en lugar de seguir las instrucciones de formato claro a la derecha del cuadro de edición? –

+0

Disculpas por el formateo, no vi las indicaciones cuando hice la publicación. – Jayd

Respuesta

1

he llegado con los siguientes como una solución alternativa:

Este es el código del filtro:

@register.filter(name='dict_value_or_null') 
def dict_value_or_null(dict, key): 
    if key in dict: 
     return dict[key] 
    else: 
     return 'null' 

Aquí es el código de la plantilla

{% for i in count %} 
     do some stuff with the value i using {{i}} which always returns the value, i.e. 1 
     email:'{{users|dict_value_or_null:i|dict_value_or_null:'email'}}' 
{% endfor %} 

Esto funciona bien, por lo Supongo que tiene mi solución. Pero todavía creo que todo esto podría haber sido mucho más fácil si hubiera una forma en el sistema de plantillas para forzar que los valores dentro de {%%} se trataran como variables, en lugar de literales.

¿Hay alguna manera de hacerlo?

Gracias por la entrada

+0

Probablemente no sea la respuesta que está buscando, pero podría echar un vistazo a Jinja2 para su motor de plantillas. Se conecta a Django bastante bien, tiene una sintaxis muy similar, pero está diseñado un poco mejor (en mi humilde opinión), especialmente cuando se trata de poder utilizar construcciones de Python en sus plantillas. –

+0

Gracias. Lo comprobaré. – Jayd

1

Prueba esto:

{% for key,val in user.items %} 
ID is {{ val.id }} and Email is {{ val.email }} 
{% endfor %} 
+0

Nota: Ha utilizado el diccionario "usuarios" en la parte superior y el usuario [i] en un intento de acceder al índice i. Asegúrese de que los nombres de los diccionarios coincidan cuando intente acceder al usuario.artículos – Abhi

+0

Gracias por esta respuesta. Sí, este es el trabajo de lo que estaba hablando, tener un bucle for dentro del otro para bucle. Ha funcionado en el código, pero ¿hay alguna otra forma de hacerlo que no requiera bucles en bucles, sino que llame al objeto de los usuarios por i? – Jayd

+0

Gracias por el comentario sobre el usuario y los usuarios. Regresé y lo cambié. – Jayd

9

Como dice Joe en su comentario, un diccionario es claramente la estructura de datos incorrecto para el recipiente exterior. Deberías estar usando una lista.

users = [] 
user = {'id':..., 'email': ...} 
users.append(user) 

...

{% for user in users %} 
    {{ user.email }} 
{% endfor %} 

Si necesita el número de cada usuario dentro del bucle, puede utilizar {{ forloop.counter }}.

+0

Necesito que el recuento comience en 1, por lo que utilicé una lista de recuento por separado, y también existirán algunos recuentos que no tienen usuarios asociados. Así que solo podría haber 2 usuarios y podría necesitar hacer un bucle y hacer otras cosas con el número de conteo 6 u 8 veces. – Jayd

+0

@Jayd Todavía no estoy seguro de entender completamente el caso de uso, pero estos son detalles que hubieran sido buenos para poner en la pregunta por adelantado para que sepamos cuál es el problema real que está tratando de resolver. –

1

hacer Código Jayd se puede utilizar con cualquiera de las listas o dict, prueba este

@register.filter(name='dict_value_or_null') 
def dict_value_or_null(dict, key): 
    try: 
     return dict[key] 
    except: 
     return 'null' 
Cuestiones relacionadas