2009-08-14 13 views
138

Mam ten kod w szablonie, który chciałbym wydrukować liczbę głosów, które każdy wybór otrzymał. głosy są po prostu słownikiem, podczas gdy wybory są obiektem modelu.jak uzyskać dostęp do elementu słownika w szablonie django?

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

podnosi wyjątek z tym komunikatem „Nie można przeanalizować pozostałą”

Odpowiedz

47

Aby echo/rozszerzyć na komentarzem Jeffa, co myślę, że należy dążyć do jest po prostu właściwością w klasie wyborem, który oblicza liczbę głosów związanych z tym obiektem:

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

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

     votes = property(calculateVotes) 

a potem w szablonie można zrobić:

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

tag szablon, to IMHO przesadą nieco do tego rozwiązania, ale to nie jest straszne rozwiązanie albo. Celem szablonów w Django jest odizolowanie od kodu w szablonach i na odwrót.

Chciałbym wypróbować powyższą metodę i zobaczyć, co generuje ORM SQL, ponieważ nie jestem pewien z góry mojej głowy, jeśli będzie wstępnie buforować właściwości i po prostu utworzyć podselekcji dla właściwości lub jeśli będzie iteracyjnie/na żądanie uruchom zapytanie, aby obliczyć liczbę głosów. Ale jeśli generuje okropne zapytania, zawsze możesz wypełnić właściwość w swoim widoku danymi, które sam zebrałeś.

+0

dzięki @john Ewart, rozwiązanie pracował dla mnie. Jestem początkującym użytkownikiem Django i Pythona i nie mogę dowiedzieć się, jak uzyskać sql wygenerowany przez ORM. – Mohamed

+0

Odpowiedź na to pytanie można znaleźć tutaj: http://docs.djangoproject.com/en/dev/faq/models/#how-can-i-see-the-raw-sql-queries-django -is-running Jest to całkiem proste i może być wyświetlane w twoim szablonie lub logowane za pomocą funkcji logowania, ale musisz pamiętać, aby włączyć DEBUG, aby to działało. –

+0

to rozwiązanie jest idealne dla problemu, jaki miałem z modelami django templating + google app engine. Chciałbym móc dwa razy zagłosować. –

15

Musisz znaleźć (lub określić) a „get” szablon, na przykład, here.

Definicja tag:

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

I jest używany jak:

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

rozważyć 'h.get (klawisz 'DEFAULT_VALUE')' z powodu rzucony wyjątek KeyError – semiomant

3

Idealnie byłoby utworzyć metodę na obiekcie wybór, który znalazł się w głosy, lub utworzyć relację między modele. Również tag szablonu, który wykonał wyszukiwanie słownika.

141

można użyć notacji DOT:

Dot wyszukiwań można podsumować jak tym: gdy system szablon napotyka kropkę w nazwie zmiennej, próbuje następujące wyszukiwań w tego zlecenia :

  • tego słownika (np foo [ "bar"])
  • atrybut wyszukiwania (np foo.bar)
  • połączenie metody (np foo.bar())
  • Lista odnośników indeks (na przykład, Foo [2])

System wykorzystuje pierwszy typ przeglądową, która działa. To logika zwarcia.

+38

W jego przypadku wybór jest zmienną. Wykonanie .choice wyszuka wartość klucza "wybór", a nie wartość klucza. – ibz

+0

+1 za informację, mimo że pytanie było rodzajem pytania "odgadnij, o czym myślę". Dzięki Wilhelm. – eficker

+1

Działa to nawet ze słownikami zagnieżdżonymi. Kod Pythona: 'my_dict [1] [2]' Kod szablonu: 'my_dict.1.2' – djsmith

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

Oto szablon:

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

Zasadniczo .items jest kluczowe Django że dzieli słownika na listę (klucz, wartość) par. Umożliwia to iterację po słowniku w szablonie Django.

+16

.items - właśnie rozwiązałeś mój problem. –

+2

to nie działa dla mnie. – anacarolinats

+0

@acarolinats (i inne) po prostu upewnij się, że iterujesz po obu kluczach, value for choices.items. To powinno nadal działać. – OldTinfoil

2

Podobny do odpowiedzi przez @russian_spy:

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

Może to być korzystne dla uszkodzi bardziej skomplikowane słowniki.

0

Zastosowanie Słownik przedmioty

 {% for key, value in my_dictionay.items %} 
      <li>{{ key }} : {{ value }}</li> 
     {% endfor %} 
Powiązane problemy