Aşağıdaki örnekte, bir veritabanı-pahalı özelliği (örnekte related_spam
) çağrıldığında model örneğinde bir öznitelik almak veya ayarlamak için cached_attr
kullanılır. Örnekte, sorguları kaydetmek için cached_spam
kullanıyorum. Ayarlarken ve değerleri alırken baskı ifadeleri koydum, böylece test edebilirim. Egg
örneğini, {{ egg.cached_spam }}
kullanarak görünümde ve görünümde geçirerek, cached_spam
çağrılarını cached_spam
'a çeviren Egg
modelindeki diğer yöntemleri kullanarak test ettim. Django'nun geliştirme sunucusundaki kabuk çıktısını bitirip test ettiğimde, özellik önbelleğinin birkaç kez kaçırılmasının yanı sıra birkaç kez başarılı bir şekilde kazanıldığını gösterdi. Tutarsız görünüyor. Aynı verilerle, küçük değişiklikler yaptığımda (baskı ifadesinin dizgisini değiştirmeden) ve yenilendiğinde (aynı verilerle), farklı miktarlarda hatalar/başarılar oldu. Bu nasıl ve neden oluyor? Bu kod yanlış mı yoksa çok sorunlu mu?Python - gelecekteki hesaplamaları önlemek için bir özelliği önbelleğe alma
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
Bu sıkıntıya karşı geldim ve bu problemi çözmenin başka bir yolunun hesaplanmış bir sonuç için bir takma ad oluşturmak üzere 'with' şablon etiketini kullanmak olduğunu fark ettim. – nedned
@humble - thx, aslında oldukça yararlı bir not. – orokusaki