В следующем примере 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