Как я могу аннулировать @cached_property в django
Привет всем, я в настоящее время использую @cached_property в классе модели и плохо люблю его удалять при сохранении, чтобы его можно было повторно заселить при следующем вызове, как я это делаю. Пример:
class Amodel():
#...model_fields....
@cached_property
def db_connection(self):
#get some thing in the db and cache here
instance = Amodel.objects.get(id=1)
variable = instance.db_connection
Amodel.objects.select_for_update().filter(id=1).update(#some variable)
#invalidate instance.db_connection
#new_variable = instance.db_connection
благодаря
Ответы
Ответ 1
Просто, как говорится в документации. Это приведет к перерасчету при следующем доступе.
class SomeClass(object):
@cached_property
def expensive_property(self):
return datetime.now()
obj = SomeClass()
print obj.expensive_property
print obj.expensive_property # outputs the same value as before
del obj.expensive_property
print obj.expensive_property # outputs new value
Ответ 2
Отредактировано в значительной степени из-за продолжающейся разработки... Теперь поддерживает несколько тегов для данного кеша_property.
Я столкнулся с аналогичной проблемой, в которой у меня был набор связанных объектов cached_property
которые потребовали одновременной аннулирования. Я решил это так:
-
Расширьте cached_property
чтобы принять значения тегов и включить класс класса decorator:
def __init__(self, func, *tags):
self.func = func
self.tags = frozenset(tags)
@classmethod
def tag(cls *tags):
return lambda f: cls(f, *tags)
-
В моих других объектах используйте мой новый cached_property.tag
decorator cached_property.tag для определения cached_property
методов cached_property
:
@cached_property.tag("foo_group")
def foo(self):
return "foo"
-
На моем объекте, который использует новый декоратор, напишите метод, чтобы аннулировать все значения cached_property
с помощью именованного тега, __dict__
по __dict__
класса экземпляра объекта. Это предотвращает случайный вызов всех методов cached_property
:
def invalidate(self, tag):
for key, value in self.__class__.__dict__.items():
if isinstance(value, cached_property) and tag in value.tags:
self.__dict__.pop(key, None)
Теперь, чтобы сделать недействительным, я просто myobject.invalidate("foo_group")
.
Ответ 3
Я создал модель Django mixin, которая отменяет все свойства @cached_property
в модели при model.refresh_from_db()
. Вы также можете просто аннулировать кешированные свойства с помощью model.invalidate_cached_properties()
.
from django.utils.functional import cached_property
class RefreshFromDbInvalidatesCachedPropertiesMixin():
def refresh_from_db(self, *args, **kwargs):
self.invalidate_cached_properties()
return super().refresh_from_db(*args, **kwargs)
def invalidate_cached_properties(self):
for key, value in self.__class__.__dict__.items():
if isinstance(value, cached_property):
self.__dict__.pop(key, None)
https://gitlab.com/snippets/1747035
Вдохновленный Томасом Баденом ответ.