Bir Django şablonundaki bir sözlük öğesine nasıl erişilir?


181

Her seçimin aldığı oy sayısını yazdırmak istiyorum. Bir şablonda bu kodu var:

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

votessadece bir sözlükken choices, bir model nesnesidir.

Bu mesajla bir istisna oluşturur:

"Could not parse the remainder"

Yanıtlar:


63

Jeff'in yorumunu yinelemek / genişletmek için, hedeflemeniz gerektiğini düşündüğüm, Seçim sınıfınızdaki bu nesneyle ilişkili oyların sayısını hesaplayan bir özelliktir:

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

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

    votes = property(calculateVotes)

Ve sonra şablonunuzda şunları yapabilirsiniz:

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

Şablon etiketi, IMHO'nun bu çözüm için biraz abartı olduğunu, ancak korkunç bir çözüm de değil. Django'daki şablonların amacı, sizi şablonlarınızdaki koddan yalıtmaktır.

Yukarıdaki yöntemi denemek ve özellikleri önbelleğe ve sadece özellik için bir alt seçim oluşturmak veya yinelemeli / açık olacaksa, başımın kapalı emin değilim olarak hangi SQL ORM üretir görmek oy sayısı hesaplamak için sorguyu çalıştırın. Ancak, iğrenç sorgular oluşturuyorsa, görünümü her zaman kendiniz topladığınız verilerle mülkü doldurabilirsiniz.


teşekkürler @john ewart, çözümünüz benim için çalıştı. Ben django ve python için acemi ve ORM oluşturulan sql almak için nasıl figureout olamaz.
Mohamed

Bu bitin cevabını burada bulabilirsiniz: docs.djangoproject.com/en/dev/faq/models/… Oldukça basit, aslında ve şablonunuzda görüntülenebilir veya bir günlük tesisinde oturum açabilirsiniz, ancak bunun çalışması için DEBUG'ı açmayı unutmayın.
John Ewart

Bu çözüm, django templating + google app engine modellerinde yaşadığım bir sorun için mükemmeldir. Keşke sana iki kez oy verebilseydim.
Conrad.Dean

5
İşe yarıyor olsa da, çok verimli değil. Bir döngü içinde sql sorguları yapıyor (kaçınmalısınız bir şey). Dict aramaları yapmak için kendi etiketinizi oluşturmak kolaydır: @ register.filter def arama (d, anahtar): eğer d ve isinstance (d, dict): return d.get (key)
dalore

Bir sınıf oluşturmak çok fazla yük; daha iyi yapılandırılmış bir sözlük, .itemsçağrı ile birleştirildiğinde (diğer cevaplardan birinde gösterildiği gibi) çok daha basit bir çözümdür.
Zags

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

Şablon:

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

Temel olarak, .itemsbir sözlüğü (key, value)Python yöntemi gibi bir çiftler listesine ayıran bir Django anahtar kelimesidir .items(). Bu, bir Django şablonundaki bir sözlük üzerinden yineleme yapılmasını sağlar.


@anacarolinats (ve diğerleri) sadece choices.items için hem anahtar hem de değer üzerinden yinelediğinizden emin olun. Hala çalışmalı.
OldTinfoil

En sonunda! Teşekkür ederim!! : D
djGrill

yani şablon motorunda () kullanılamaz. BTW Teşekkürler benim için teşekkürler.
BlaShadow

6
Soruya güzel özlü bir çözüm. Açıklığa kavuşturmak için, itemsbir Django anahtar sözcüğü değil, sözlükte bir Python yöntemi çağrısıdır. As Alex Martelli işaret temelde aynıdır iteritems. Wilhelm'in cevapladığı gibi, sözlük araması nokta aramaları için 3. sıradadır. Sözlüğünüzde adlı bir öğeniz varsa 'items', tuples listesi yerine bu değeri geri alırsınız. Test {'items':'oops'}etmek için: sözlüğünüze ekleyin ve 'oops' kelimesinden madde işaretli harflerin bir listesini alırsınız
cod3monk3y

1
Kullanım collections.OrderedDict yineleme sırasını kontrol etmek
dnalow

186

nokta gösterimini kullanabilirsiniz:

Nokta aramaları şu şekilde özetlenebilir: şablon sistemi değişken adında bir nokta ile karşılaştığında, aşağıdaki aramaları bu sırayla dener:

  • Sözlük araması (ör. Foo ["bar"])
  • Özellik araması (ör. Foo.bar)
  • Yöntem çağrısı (ör. Foo.bar ())
  • Liste indeksi araması (ör. Foo [2])

Sistem çalışan ilk arama türünü kullanır. Kısa devre mantığı.


44
Onun durumunda seçim bir değişkendir. .Choice yapmak, anahtar seçiminin değerini değil, "seçim" anahtarının değerini arar.
ibz

Sorunun bir tür "ne düşündüğümü tahmin et" sorusu olmasına rağmen bilgi için +1. Teşekkürler Wilhelm.
eficker

1
Bu, iç içe sözlüklerle bile çalışır. Python kodu: my_dict[1][2]Şablon kodu:my_dict.1.2
djsmith

2
@ JCLeitão Çünkü doğru sürüm d.key.1- ikinci not.
Izkata

3
Bununla ilgili dokümanları kontrol edin ... "1.6 docs.djangoproject.com/en/1.6/topics/templates/#variables " adresinden : {{foo.bar}} gibi bir şablon ifadesindeki “bar” ın yorumlanacağına dikkat edin değişmez bir dize olarak ve şablon bağlamında varsa "bar" değişkeninin değerini kullanmamak.
jamesc

25

Örneğin, burada bir 'get' şablon etiketi bulmanız (veya tanımlamanız) gerekir .

Etiket tanımı:

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

Ve şu şekilde kullanılır:

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

3
h.get(key,'default_value')
KeyError

9

Sözlük Öğelerini Kullan:

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


6

@Russian_spy tarafından verilen cevaba benzer:

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

Bu, daha karmaşık sözlükleri yıkmak için uygun olabilir.


3

İdeal olarak, seçim nesnesinde oylarda kendini bulan bir yöntem veya modeller arasında bir ilişki yaratabilirsiniz. Sözlük aramasını yapan bir şablon etiketi de işe yarayacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.