Django टेम्पलेट कैसे एक चर के साथ एक शब्दकोश मूल्य देखने के लिए


234
mydict = {"key1":"value1", "key2":"value2"}

एक Django टेम्पलेट में एक मूल्य के शब्दकोश देखने के लिए नियमित रूप से रास्ता है {{ mydict.key1 }}, {{ mydict.key2 }}। क्या होगा यदि कुंजी एक लूप वेरिएबल है? अर्थात:

{% for item in list %} # where item has an attribute NAME
  {{ mydict.item.NAME }} # I want to look up mydict[item.NAME]
{% endfor %}

mydict.item.NAMEविफल रहता है। इसे कैसे ठीक करें?

जवाबों:


362

एक कस्टम टेम्पलेट फ़िल्टर लिखें:

from django.template.defaulttags import register
...
@register.filter
def get_item(dictionary, key):
    return dictionary.get(key)

(मैं इसका उपयोग करता हूं .getकि यदि कुंजी अनुपस्थित है, तो यह कोई नहीं लौटाता है। यदि आप ऐसा करते हैं तो dictionary[key]यह KeyErrorतब बढ़ेगा ।)

उपयोग:

{{ mydict|get_item:item.NAME }}

16
Django कस्टम टेम्पलेट टैग प्रलेखन , भविष्य में इसे खोजने वालों के लिए।
जेफ

281
यह डिफ़ॉल्ट रूप से क्यों नहीं बनाया गया है? :-(
बेरिस्लाव लोपैक

11
मुझे लगता है कि @ जेफ का मतलब Django कस्टम टेम्पलेट फ़िल्टर प्रलेखन
जॉर्ज

5
जिंजा 2 में {{mydict [की]}}
एवगेनी

9
क्या फ़िल्टर view.py, कुछ extra filter.py, or what file में जाता है?
एलन

56

लूप में शब्दकोश से कुंजी और मान दोनों प्राप्त करें:

{% for key, value in mydict.items %}
    {{ value }}
{% endfor %}

मुझे यह पढ़ने में आसान लगता है और यह विशेष कोडिंग की आवश्यकता से बचा जाता है। मुझे आमतौर पर वैसे भी लूप के अंदर कुंजी और मूल्य की आवश्यकता होती है।


28
उन्होंने एक तानाशाह की गणना करने के लिए नहीं कहा (जैसा कि आप दिखाते हैं) - उन्होंने एक चर कुंजी दिए गए हुक्म के मूल्य को प्राप्त करने के लिए कहा। आपका प्रस्ताव समाधान प्रदान नहीं करता है।
डगमगाते हुए

यह एक समाधान है (बस बहुत ही अकुशल) क्योंकि आप तानाशाह की वस्तुओं की गणना कर सकते हैं और फिर सूची से कुंजी के साथ मिलान कर सकते हैं।
डायलनयुंग

1
ध्यान दें कि यह काम नहीं करता है यदि आप जिस शब्दकोश तक पहुंचने की कोशिश कर रहे हैं, उसके अंदर एक और शब्दकोश है।
J0ANMM

यदि आपके मान dicts हैं, तो आप उनकी कुंजियों और मूल्यों को संसाधित करने के लिए लूप के लिए एक और शामिल कर सकते हैं लेकिन संभावना है कि जटिलता आपको कस्टम फ़िल्टर का उपयोग करने के लायक मान रही है जैसा कि @ culebron के उत्तर में वर्णित है।
पॉल व्हिप

37

आप डिफ़ॉल्ट रूप से नहीं कर सकते। डॉट विशेषता देखने / कुंजी देखने / स्लाइस के लिए विभाजक / ट्रिगर है।

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

  • शब्दकोश खोज। उदाहरण: फू ["बार"]
  • देखने का गुण। उदाहरण: foo.bar
  • सूची-सूचकांक लुकअप। उदाहरण: फू [बार]

लेकिन आप एक फ़िल्टर बना सकते हैं जो आपको एक तर्क में पास करने देता है:

https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#writing-custom-template-filters

@register.filter(name='lookup')
def lookup(value, arg):
    return value[arg]

{{ mydict|lookup:item.name }}

1
मैं अभी भी उपयोग करूँगा return value.get(arg)क्योंकि अगर कोई कुंजी मौजूद नहीं है, तो वह KeyError अपवाद नहीं फेंकेगा।
स्लेजमा

3

मेरे लिए template_filters.pyमेरे ऐप में एक पायथन फ़ाइल बनाई गई है जिसके नीचे सामग्री है

# coding=utf-8
from django.template.base import Library

register = Library()


@register.filter
def get_item(dictionary, key):
    return dictionary.get(key)

उपयोग की तरह है जो culebrón ने कहा:

{{ mydict|get_item:item.NAME }}

क्यों register = Library()? यह क्या करता है ?
एमडी। खैरुल बसर

2
यदि आप चाहते हैं कि आपके सभी टेम्पलेट आपके नए फ़िल्टर के बारे में जानें, तो आपको इसे django.template.base.Libraryकक्षा में पंजीकृत करना होगा । द्वारा register = Library()हम उस वर्ग को filterत्वरित करते हैं और अपनी आवश्यकता तक पहुंचने के लिए इसके अंदर फ़ंक्शन एनोटेटर का उपयोग करते हैं।
अमीनादिमी

2

मेरी भी ऐसी ही स्थिति थी। हालांकि मैंने एक अलग समाधान का उपयोग किया।

अपने मॉडल में मैं एक संपत्ति बनाता हूं जो शब्दकोश खोज करता है। टेम्पलेट में मैं तब संपत्ति का उपयोग करता हूं।

मेरे मॉडल में: -

@property
def state_(self):
    """ Return the text of the state rather than an integer """
    return self.STATE[self.state]

मेरे टेम्पलेट में: -

The state is: {{ item.state_ }}

1

चूँकि मैं टिप्पणी नहीं कर सकता, इसलिए मुझे उत्तर के रूप में ऐसा
करने दो : culebrón के उत्तर या युजी 'टोमिता' के उत्तर का निर्माण करने के लिए , फंक्शन में दिया गया शब्दकोश एक स्ट्रिंग के रूप में है, इसलिए शायद ast का उपयोग करें इस उदाहरण की तरह, पहले स्ट्रिंग को शब्दकोष में बदलने के लिए शाब्दिक_कावल

इस संपादन के साथ, कोड इस तरह दिखना चाहिए:

@register.filter(name='lookup')
def lookup(value, arg):
    dictionary = ast.literal_eval(value)
    return value.get(arg)

{{ mydict|lookup:item.name }}

0

पर्यावरण: Django 2.2

  1. उदाहरण कोड:


    from django.template.defaulttags import register

    @register.filter(name='lookup')
    def lookup(value, arg):
        return value.get(arg)

मैंने यह कोड अपने प्रोजेक्ट फ़ोल्डर में port_oliilgr नाम की template_filters.py नाम की फ़ाइल में रखा था

  1. कोई फर्क नहीं पड़ता कि आपने अपना फ़िल्टर कोड कहां रखा है, सुनिश्चित करें कि आपके पास उस फ़ोल्डर में __init__.py है

  2. उस फ़ाइल को लायब्रेरी सेक्शन में अपने प्रॉजेक्टफ़ोल्डर / सेटिंग्स ओफ़्फ़ॉर्म फ़ाइल में जोड़ें। मेरे लिए, यह portfoliomgr / settings.py है



    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
                'libraries':{
                    'template_filters': 'portfoliomgr.template_filters',
                }
            },
        },
    ]

  1. अपने HTML कोड में लाइब्रेरी लोड करें

    
    {% load template_filters %}
    

-2

env: django 2.1.7

राय:

dict_objs[query_obj.id] = {'obj': query_obj, 'tag': str_tag}
return render(request, 'obj.html', {'dict_objs': dict_objs})

टेम्पलेट:

{% for obj_id,dict_obj in dict_objs.items %}
<td>{{ dict_obj.obj.obj_name }}</td>
<td style="display:none">{{ obj_id }}</td>
<td>{{ forloop.counter }}</td>
<td>{{ dict_obj.obj.update_timestamp|date:"Y-m-d H:i:s"}}</td>

1
टेम्पलेट कोड {{ dict_obj.obj.obj_name }}इस मामले में पायथन कोड के बराबर है dict_obj["obj"]["obj_name"], हालांकि, सवाल समकक्ष के बारे में है dict_obj[obj][obj_name]
फ्लिम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.