Django टेम्पलेट में एक शब्दकोश तत्व कैसे एक्सेस करें?


181

मैं प्रत्येक पसंद को मिले वोटों की संख्या का प्रिंट आउट लेना चाहता हूं। मेरे पास एक टेम्पलेट में यह कोड है:

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

voteschoicesएक मॉडल वस्तु है, जबकि सिर्फ एक शब्दकोश है।

यह इस संदेश के साथ एक अपवाद उठाता है:

"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 क्या उत्पन्न करता है क्योंकि मुझे यकीन नहीं है कि यह मेरे सिर के ऊपर से निकलेगा, अगर यह गुणों को प्री-कैश कर देगा और संपत्ति के लिए सबसिलेक्ट बना देगा या यदि यह iteratively / on- वोट संख्या की गणना करने के लिए क्वेरी चलाएं। लेकिन अगर यह नृशंस प्रश्न उत्पन्न करता है, तो आप हमेशा अपने द्वारा एकत्र किए गए डेटा के साथ अपने विचार में संपत्ति को आबाद कर सकते हैं।


धन्यवाद @ जॉन इवर्ट, आपके समाधान ने मेरे लिए काम किया। मैं django और अजगर के लिए नौसिखिया हूं और यह पता नहीं लगा सकता कि ओआरएम उत्पन्न होने वाले एसक्यूएल को कैसे प्राप्त किया जाए।
मोहम्मद

आप उस बिट का उत्तर यहां पा सकते हैं: docs.djangoproject.com/en/dev/faq/models/… यह काफी सरल है, वास्तव में और आपके टेम्पलेट में प्रदर्शित किया जा सकता है, या लॉगिंग सुविधा से लॉग इन किया जा सकता है, लेकिन आपको करना होगा काम करने के लिए DEBUG चालू करना याद रखें।
जॉन इवर्ट

यह समाधान एक समस्या के लिए एकदम सही है जो मैं django templating + google ऐप इंजन मॉडल के साथ कर रहा हूं। काश मैं आपको दो बार वोट कर सकता।
कॉनराड

5
हालांकि यह काम करता है, यह बहुत कुशल नहीं है। यह लूप में sql क्वेरी कर रहा है (कुछ आपको बचना चाहिए)। तानाशाह लुकअप करने के लिए अपना खुद का टैग बनाना आसान है: @ register.filter def लुकअप (d, की): if d और isinstance (d, dict): return d.get (key)
dalore

एक वर्ग बनाना बहुत अधिक उपरि तरीका है; एक बेहतर संरचित शब्दकोश, .itemsकॉल के साथ संयुक्त (जैसा कि अन्य उत्तरों में से एक में सचित्र) एक बहुत सरल समाधान है।
ज़ग्स

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 (और अन्य) बस यह सुनिश्चित करें कि आप दोनों कुंजी पर पसंद करते हैं, चुनाव के लिए मूल्य। यह अभी भी काम करना चाहिए।
ओल्डटाइनफॉइल

आखिरकार! धन्यवाद!! : D
djGrill

इसलिए टेम्पलेट इंजन में उपयोग नहीं किया जा सकता ()। BTW मेरे लिए धन्यवाद।
BlaShadow

6
सवाल का अच्छा संक्षिप्त समाधान। स्पष्ट करने के लिए, itemsशब्दकोश पर एक पायथन विधि कॉल है, न कि एक Django कीवर्ड। जैसा कि एलेक्स मार्टेली बताते हैं कि यह मूल रूप से जैसा है iteritems। जैसा कि विल्हेम ने उत्तर दिया था, डिक्शनरी लुकअप डॉट लुकिंग के लिए पूर्ववर्ती 3 जी है। यदि आपके पास अपने शब्दकोश में कोई आइटम है 'items', तो आपको ट्यूपल्स की सूची के बजाय वापस मान मिलेगा। परीक्षण करने के लिए: {'items':'oops'}अपने शब्दकोश में जोड़ें और आपको '
ऊप्स

1
संग्रह का उपयोग करें। पुनरावृति के आदेश को नियंत्रित करने के लिए
संपादित करें

185

आप डॉट नोटेशन का उपयोग कर सकते हैं:

डॉट लुकअप को इस तरह संक्षेप में प्रस्तुत किया जा सकता है: जब टेम्पलेट सिस्टम एक चर नाम में एक डॉट का सामना करता है, तो यह इस क्रम में निम्नलिखित लुकअप की कोशिश करता है:

  • शब्दकोश खोज (जैसे, फू ["बार"])
  • देखने का गुण (जैसे, foo.bar)
  • विधि कॉल (जैसे, foo.bar ())
  • सूची-अनुक्रमण लुकअप (उदाहरण के लिए, foo [2])

सिस्टम पहले लुकअप प्रकार का उपयोग करता है जो काम करता है। यह शॉर्ट-सर्किट लॉजिक है।


44
उनके मामले में विकल्प एक चर है। डूइंग .choice कुंजी "पसंद" के लिए मूल्य को देखेंगे, बल्कि कुंजी विकल्प के लिए मूल्य।
आइबज

जानकारी के लिए +1, भले ही प्रश्न "अनुमान लगा रहा था कि मैं क्या सोच रहा हूं" प्रश्न की तरह था। धन्यवाद विल्हेम।
eficker

1
यह भी नेस्टेड शब्दकोशों के साथ काम करता है। पायथन कोड: my_dict[1][2]टेम्पलेट कोड:my_dict.1.2
djsmith

2
@ JCLeitão सही संस्करण है d.key.1- दूसरा.
इज़ाका

3
इस पर डॉक्स की जांच करें ... "1.6 docs.djangoproject.com/en/1.6/topics/templates/#variables " से: ध्यान दें कि {{foo.bar}} जैसे टेम्पलेट अभिव्यक्ति में "बार" की व्याख्या की जाएगी। एक शाब्दिक स्ट्रिंग के रूप में और चर "बार" के मूल्य का उपयोग न करने पर, यदि कोई टेम्पलेट संदर्भ में मौजूद है।
jamesc

25

उदाहरण के लिए, आपको 'get' टेम्पलेट टैग ढूंढना (या परिभाषित करना) है

टैग की परिभाषा:

@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

आदर्श रूप से, आप उस पसंद की वस्तु पर एक विधि बनाएंगे जो स्वयं को वोटों में मिली हो, या मॉडल के बीच संबंध बनाती हो। एक टेम्पलेट टैग जो शब्दकोश देखने का कार्य करता है, वह भी काम करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.