จะเข้าถึงองค์ประกอบพจนานุกรมในเทมเพลต Django ได้อย่างไร


181

ฉันต้องการพิมพ์จำนวนคะแนนที่แต่ละตัวเลือกได้รับ ฉันมีรหัสนี้ในแม่แบบ:

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

votesเป็นเพียงพจนานุกรมในขณะที่choicesเป็นวัตถุรูปแบบ

มันทำให้เกิดข้อยกเว้นด้วยข้อความนี้:

"Could not parse the remainder"

คำตอบ:


63

เพื่อสะท้อน / ขยายความคิดเห็นของเจฟฟ์สิ่งที่ฉันคิดว่าคุณควรตั้งเป้าหมายคือคุณสมบัติในคลาสตัวเลือกของคุณซึ่งคำนวณจำนวนคะแนนที่เกี่ยวข้องกับวัตถุนั้น:

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

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

    votes = property(calculateVotes)

จากนั้นในเทมเพลตของคุณคุณสามารถ:

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

เทมเพลตแท็กคือ IMHO มากเกินไปสำหรับการแก้ปัญหานี้ แต่ก็ไม่ใช่วิธีการแก้ปัญหาที่เลวร้ายเช่นกัน เป้าหมายของเทมเพลตใน Django คือการป้องกันคุณจากโค้ดในเทมเพลตและในทางกลับกัน

ฉันจะลองวิธีข้างต้นและดูว่า SQL ORM สร้างขึ้นมาเพราะฉันไม่แน่ใจว่าอยู่ด้านบนของหัวถ้ามันจะแคชคุณสมบัติล่วงหน้าและเพียงสร้างการเลือกย่อยสำหรับคุณสมบัติหรือถ้ามันจะซ้ำ / on- ความต้องการใช้งานแบบสอบถามเพื่อคำนวณการนับคะแนน แต่ถ้ามันสร้างการสืบค้นที่หยาบคายคุณสามารถเติมคุณสมบัติในมุมมองของคุณด้วยข้อมูลที่คุณรวบรวมเองได้เสมอ


ขอบคุณ @john ewart ทางออกของคุณใช้ได้สำหรับฉัน ฉันเป็นมือใหม่กับ django และ python และไม่สามารถคิดได้ว่าจะหา sql ที่ ORM สร้างขึ้นได้อย่างไร
Mohamed

คุณสามารถหาคำตอบสำหรับบิตนั้นได้ที่นี่: docs.djangoproject.com/en/dev/faq/models/ ...... มันค่อนข้างง่ายจริง ๆ แล้วสามารถแสดงในเทมเพลตของคุณหรือถูกบันทึกด้วยเครื่องมือบันทึก แต่คุณต้อง อย่าลืมเปิดใช้ DEBUG เพื่อให้สิ่งนี้ทำงาน
John Ewart

วิธีการแก้ปัญหานี้เหมาะสำหรับปัญหาที่ฉันมีกับ django templating + รุ่นของแอป google engine ฉันหวังว่าฉันจะลงคะแนนคุณสองครั้ง
Conrad.Dean

5
แม้ว่ามันจะใช้งานได้ แต่ก็ไม่ได้มีประสิทธิภาพมากนัก มันกำลังทำแบบสอบถาม SQL ในวง (สิ่งที่คุณควรหลีกเลี่ยง) การสร้างแท็กของคุณเองเพื่อทำการค้นหาแบบ Dict นั้นเป็นเรื่องง่าย: @ register.filter def lookup (d, key): ถ้า d และ isinstance (d, dict): return d.get (คีย์)
dalore

การสร้างชั้นเรียนเป็นวิธีที่เหนือศีรษะมากเกินไป พจนานุกรมที่มีโครงสร้างที่ดีกว่ารวมกับการ.itemsโทร (ดังที่แสดงไว้ในคำตอบอื่น) เป็นวิธีที่ง่ายกว่ามาก
Zags

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

นี่คือแม่แบบ:

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

โดยทั่วไป.itemsเป็นคำหลักที่แยก Django พจนานุกรมในรายการของคู่เหมือนวิธีหลาม(key, value) .items()สิ่งนี้ทำให้เกิดการวนซ้ำในพจนานุกรมในเทมเพลต Django


@anacarolinats (และอื่น ๆ ) เพียงให้แน่ใจว่าคุณวนซ้ำทั้งคีย์ค่าสำหรับ options.items มันควรจะยังคงทำงาน
OldTinfoil

ที่สุด! ขอบคุณ!! : D
djGrill

ดังนั้นในเทมเพลตเอนจินไม่สามารถใช้ () BTW ขอบคุณ wotks สำหรับฉัน
BlaShadow

6
คำตอบที่กระชับสำหรับคำถาม เพื่อชี้แจงitemsคือการเรียกวิธี Python ในพจนานุกรมไม่ใช่คำหลัก Django ในฐานะที่เป็นจุดเล็กซ์เทลออกมาiteritemsก็เป็นเช่นเดียวกับ ดังที่วิลเฮล์มตอบการค้นหาพจนานุกรมนั้นมีความสำคัญเป็นอันดับที่ 3 สำหรับการค้นหาดอท หากคุณมีรายการอยู่ในพจนานุกรมชื่อของ'items'คุณคุณจะได้รับค่านั้นกลับคืนแทนที่จะเป็นรายการอันดับ วิธีทดสอบ: เพิ่ม{'items':'oops'}ในพจนานุกรมของคุณและคุณจะได้รับรายการสัญลักษณ์แสดงหัวข้อย่อยจากคำว่า 'oops'
cod3monk3y

1
ใช้คอลเลกชันสั่งทำเพื่อควบคุมลำดับของการวนซ้ำ
dnalow

186

คุณสามารถใช้เครื่องหมายจุด:

การค้นหา Dot สามารถสรุปได้ดังนี้: เมื่อระบบแม่แบบพบจุดในชื่อตัวแปรมันจะทำการค้นหาต่อไปนี้ตามลำดับ:

  • การค้นหาพจนานุกรม (เช่น foo ["bar"])
  • การค้นหาแอตทริบิวต์ (เช่น foo.bar)
  • การเรียกใช้วิธี (เช่น foo.bar ())
  • การค้นหาดัชนีรายการ (เช่น foo [2])

ระบบใช้ประเภทการค้นหาแรกที่ใช้งานได้ มันเป็นตรรกะการลัดวงจร


44
ในกรณีที่เขาเลือกเป็นตัวแปร การเลือก. choice จะค้นหาค่าของคีย์ "ตัวเลือก" แทนค่าสำหรับตัวเลือกคีย์
ibz

+1 สำหรับข้อมูลแม้ว่าคำถามจะเป็นคำถามแบบ "คาดเดาสิ่งที่ฉันกำลังคิด" ขอบคุณวิลเฮล์ม
eficker

1
วิธีนี้ใช้ได้กับพจนานุกรมที่ซ้อนกัน รหัส Python: รหัสmy_dict[1][2]แม่แบบ:my_dict.1.2
djsmith

2
@ JCLeitãoเพราะรุ่นที่ถูกต้องคือd.key.1- บันทึกที่สอง.
Izkata

3
ตรวจสอบเอกสารเกี่ยวกับสิ่งนี้แม้ว่า ... จาก "1.6 docs.djangoproject.com/en/1.6/topics/templates/#variables ": โปรดทราบว่า "บาร์" ในนิพจน์เทมเพลตเช่น {{foo.bar}} จะถูกตีความ เป็นสตริงตัวอักษรและไม่ได้ใช้ค่าของตัวแปร“ บาร์” หากมีอยู่ในบริบทแม่แบบ
jamesc

25

คุณต้องไปหา (หรือกำหนด) ว่า 'ได้รับ' แท็กแม่แบบเช่นที่นี่

คำจำกัดความของแท็ก:

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

และมันถูกใช้เช่น:

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

3
พิจารณาh.get(key,'default_value')เพราะ KeyError
รอบรองชนะเลิศ



6

คล้ายกับคำตอบโดย @russian_spy:

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

สิ่งนี้อาจเหมาะสำหรับการทำลายพจนานุกรมที่ซับซ้อนมากขึ้น


3

เป็นการดีที่คุณจะสร้างวิธีการในการเลือกวัตถุที่พบว่าตัวเองอยู่ในการลงคะแนนหรือสร้างความสัมพันธ์ระหว่างแบบจำลอง แท็กแม่แบบที่ดำเนินการค้นหาพจนานุกรมก็สามารถใช้ได้เช่นกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.