web-dev-qa-db-fra.com

Comment accéder à un élément de dictionnaire dans un modèle Django?

Je voudrais imprimer le nombre de votes que chaque choix a eu. J'ai ce code dans un template:

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

votes n'est qu'un dictionnaire alors que choices est un objet modèle.

Il soulève une exception avec ce message:

"Could not parse the remainder"
163
Mohamed

Pour faire écho au commentaire de Jeff, je pense que vous devriez viser simplement une propriété de votre classe Choice qui calcule le nombre de votes associé à cet objet:

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

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

        votes = property(calculateVotes)

Et puis dans votre modèle, vous pouvez faire:

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

La balise template est un peu exagérée pour IMHO pour cette solution, mais ce n’est pas une solution terrible non plus. Le but des templates dans Django est de vous isoler du code de vos templates et inversement.

Je voudrais essayer la méthode ci-dessus et voir ce que l'ORM génère SQL car je ne suis pas sûr de savoir s'il pré-cache les propriétés et crée simplement une sous-sélection pour la propriété ou si elle sera itérative/sur la demande lance la requête pour calculer le nombre de votes. Mais s'il génère des requêtes atroces, vous pouvez toujours renseigner la propriété dans votre vue avec les données que vous avez collectées.

60
John Ewart
choices = {'key1':'val1', 'key2':'val2'}

Voici le modèle:

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

Fondamentalement, .items est un mot clé Django qui divise un dictionnaire en une liste de paires (key, value), un peu comme la méthode Python _ .items(). Cela active l'itération sur un dictionnaire dans un modèle Django.

258
russian_spy

vous pouvez utiliser la notation par points:

Les recherches de points peuvent être résumées comme suit: lorsque le système de modèles rencontre un point dans un nom de variable, il essaie les recherches suivantes, dans cet ordre:

  • Recherche dans le dictionnaire (par exemple, foo ["bar"])
  • Recherche d'attribut (par exemple, foo.bar)
  • Appel de méthode (par exemple, foo.bar ())
  • Recherche dans l'index de liste (par exemple, foo [2])

Le système utilise le premier type de recherche qui fonctionne. C’est la logique de court-circuit.

167
Wilhelm

Vous devez rechercher (ou définir) une balise de modèle "get", par exemple, here .

La définition de la balise:

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

Et il est utilisé comme:

{% for o in objects %}
  <li>{{ dictionary|hash:o.id }}</li>
{% endfor %}
21
Ned Batchelder

Utiliser les éléments du dictionnaire

        {% for key, value in my_dictionay.items %}
          <li>{{ key }} : {{ value }}</li>
        {% endfor %}
6
Priyanshu Chauhan

Django_template_filter nom du filtre get_value_from_dict

{{ your_dict|get_value_from_dict:your_key }}
5
Nick Korolkov

Similaire à la réponse de @russian_spy:

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

Cela pourrait être utile pour décomposer des dictionnaires plus complexes.

4
Adam Starrh

Idéalement, vous devriez créer une méthode sur l'objet de choix qui se trouve dans les votes ou créer une relation entre les modèles. Une balise de modèle qui effectue la recherche dans le dictionnaire fonctionnerait également.

3
Jeff Ober