2009-08-14 16 views
138

Tengo este código en la plantilla, que me gustaría imprimir el número de votos que obtuvo cada opción. votos es solo un diccionario, mientras que las opciones son un objeto modelo.cómo acceder al elemento del diccionario en la plantilla django?

{% for choice in choices %} 
    {{choice.choice}} - {{votes[choice.id]}} <br /> 
{% endfor %} 

se lanza una excepción con este mensaje "No se pudo analizar el resto"

Respuesta

47

a ECHO/se extienden sobre el comentario de Jeff, lo que creo que debe apuntar para es simplemente una propiedad en su mejor elección que calcula el número de votos asociados con ese objeto:

class Choice(models.Model): 
     text = models.CharField(max_length=200) 

     def calculateVotes(self): 
      return Vote.objects.filter(choice = self).count() 

     votes = property(calculateVotes) 

Y luego en su plantilla , se puede hacer:

{% for choice in choices %} 
      {{choice.choice}} - {{choice.votes}} <br /> 
    {% endfor %} 

La etiqueta de plantilla, es mi humilde opinión un poco exagerado para esta solución, pero no es una solución terrible. El objetivo de las plantillas en Django es aislarlo del código en sus plantillas y viceversa.

Probaría el método anterior y vería qué SQL genera el ORM, ya que no estoy seguro de antemano si precacheará las propiedades y solo creará una subselección para la propiedad o si lo hará iterativamente/bajo demanda ejecutar la consulta para calcular el conteo de votos. Pero si genera consultas atroces, siempre puede completar la propiedad en su vista con los datos que ha recopilado usted mismo.

+0

gracias @ John Ewart, su solución trabajaron para mí. Soy novato en django y python y no puedo encontrar la forma de obtener el sql que generó ORM. – Mohamed

+0

Puede encontrar la respuesta a ese bit aquí: http://docs.djangoproject.com/en/dev/faq/models/#how-can-i-see-the-raw-sql-queries-django -es-running Es bastante simple, en realidad, y puede mostrarse en su plantilla, o registrarse con un recurso de registro, pero debe recordar activar DEBUG para que esto funcione. –

+0

esta solución es perfecta para un problema que he tenido con plantillas django + modelos de motores de aplicaciones de google. Desearía poder votar dos veces. –

15

Es necesario encontrar (o definir) una 'conseguir' etiqueta de plantilla, por ejemplo, here.

La definición de la etiqueta:

@register.filter 
def hash(h, key): 
    return h[key] 

y se usa como:

{% for o in objects %} 
    <li>{{ dictionary|hash:o.id }}</li> 
{% endfor %} 
+1

consideran 'h.get (clave, 'default_value')' debido KeyError – semiomant

3

Lo ideal sería crear un método en el objeto elección que se encontró en votos, o crear una relación entre el modelos. También funcionaría una etiqueta de plantilla que realizara la búsqueda del diccionario.

141

puede utilizar la notación de puntos:

búsquedas de puntos se pueden resumir como esto: cuando el sistema de plantillas encuentra un punto en un nombre de variable, que trata las siguientes operaciones de búsqueda, en este orden :

  • Diccionario de búsqueda (por ejemplo, foo [ "bar"])
  • atributo de búsqueda (por ejemplo, foo.bar)
  • llamada al método (por ejemplo, foo.bar())
  • Lista-índice de búsqueda (por ejemplo, foo [2])

El sistema utiliza el primero de búsqueda tipo que funciona. Es lógica de cortocircuito.

+38

En su caso, la elección es una variable. Haciendo .choice buscará el valor de la clave "elección" en lugar del valor para la elección de la tecla. – ibz

+0

+1 por la información, a pesar de que la pregunta era una especie de pregunta "adivina lo que estoy pensando". Gracias Wilhelm. – eficker

+1

Esto incluso funciona con diccionarios anidados. Código de Python: 'my_dict [1] [2]' Código de plantilla: 'my_dict.1.2' – djsmith

216
choices = {'key1':'val1', 'key2':'val2'} 

Aquí está la plantilla:

 
<ul> 
{% for key, value in choices.items %} 
    <li>{{key}} - {{value}}</li> 
{% endfor %} 
</ul> 

Básicamente, .items es una palabra clave Django que divide un diccionario en una lista de pares (clave, valor). Esto permite la iteración sobre un diccionario en una plantilla de Django.

+16

.items: acabas de resolver mi problema. –

+2

no funcionó para mí. – anacarolinats

+0

@anacarolinats (y otros) simplemente asegúrate de repetir la clave, value for choices.items. Debería funcionar. – OldTinfoil

2

Similar a la respuesta por @russian_spy:

<ul> 
{% for choice in choices.items %} 
    <li>{{choice.0}} - {{choice.1}}</li> 
{% endfor %} 
</ul> 

Esto podría ser adecuado para romper los diccionarios más complejas.

0

utilizar el diccionario Artículos

 {% for key, value in my_dictionay.items %} 
      <li>{{ key }} : {{ value }}</li> 
     {% endfor %} 
Cuestiones relacionadas