निम्नलिखित उदाहरण में, cached_attr
का उपयोग मॉडल उदाहरण पर एक विशेषता प्राप्त करने या सेट करने के लिए किया जाता है जब डेटाबेस-महंगी संपत्ति (related_spam
उदाहरण में) कहा जाता है। उदाहरण में, मैं प्रश्नों को सहेजने के लिए cached_spam
का उपयोग करता हूं। जब मैं मूल्यों को प्राप्त करता हूं और मूल्य प्राप्त करते समय प्रिंट विवरण डालता हूं ताकि मैं इसका परीक्षण कर सकूं। मैं दृश्य में एक Egg
उदाहरण पास करके और {{ egg.cached_spam }}
का उपयोग कर देखने के लिए, साथ ही साथ Egg
मॉडल कि खुद cached_spam
को कॉल करने पर अन्य तरीकों में एक दृश्य में परीक्षण किया गया। जब मैंने Django के विकास सर्वर में खोल आउटपुट को समाप्त और परीक्षण किया, तो दिखाया गया कि विशेषता कैश कई बार याद किया गया था, साथ ही सफलतापूर्वक कई बार प्राप्त हुआ था। ऐसा असंगत प्रतीत होता है। उसी डेटा के साथ, जब मैंने छोटे बदलाव किए (जैसे प्रिंट स्टेटमेंट स्ट्रिंग को बदलना उतना ही छोटा) और रीफ्रेश किया गया (सभी समान डेटा के साथ), मिस/सफलताओं की अलग-अलग मात्रा में हुई। यह कैसे और क्यों हो रहा है? क्या यह कोड गलत या अत्यधिक समस्याग्रस्त है?पायथन - भविष्य की गणना से बचने के लिए एक संपत्ति को कैश करना
class Egg(models.Model):
... fields
@property
def related_spam(self):
# Each time this property is called the database is queried (expected).
return Spam.objects.filter(egg=self).all() # Spam has foreign key to Egg.
@property
def cached_spam(self):
# This should call self.related_spam the first time, and then return
# cached results every time after that.
return self.cached_attr('related_spam')
def cached_attr(self, attr):
"""This method (normally attached via an abstract base class, but put
directly on the model for this example) attempts to return a cached
version of a requested attribute, and calls the actual attribute when
the cached version isn't available."""
try:
value = getattr(self, '_p_cache_{0}'.format(attr))
print('GETTING - {0}'.format(value))
except AttributeError:
value = getattr(self, attr)
print('SETTING - {0}'.format(value))
setattr(self, '_p_cache_{0}'.format(attr), value)
return value
मैं इस झुंझलाहट के खिलाफ आया था और महसूस किया कि इस समस्या को हल करने के लिए एक और तरीका परिकलित परिणाम के लिए एक अन्य नाम बनाना 'with' टेम्पलेट टैग का उपयोग करने के लिए है। – nedned
@ हम्बल - thx, यह वास्तव में एक बहुत उपयोगी नोट है। – orokusaki