use*_*168 23 django django-models django-views
大家好我现在正在模型类上使用@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
Run Code Online (Sandbox Code Playgroud)
谢谢
iso*_*lev 41
正如文档所说,只是del .这将导致下次访问时重新计算.
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
Run Code Online (Sandbox Code Playgroud)
我创建了一个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)
Run Code Online (Sandbox Code Playgroud)
https://gitlab.com/snippets/1747035
受到Thomas Baden的回答的启发。
由于正在进行中的开发,因此进行了大量编辑...现在支持给定cached_property的多个标签。
我遇到了类似的问题,其中我有一组相关cached_property
对象,所有这些对象都需要同时失效。我以这种方式解决了这个问题:
扩展cached_property
以接受标签值并包括装饰器类方法:
def __init__(self, func, *tags):
self.func = func
self.tags = frozenset(tags)
@classmethod
def tag(cls *tags):
return lambda f: cls(f, *tags)
Run Code Online (Sandbox Code Playgroud)在其他对象中,使用新的cached_property.tag
装饰器类cached_property
方法定义标记的方法:
@cached_property.tag("foo_group")
def foo(self):
return "foo"
Run Code Online (Sandbox Code Playgroud)在使用新装饰器的对象上,编写一种方法,cached_property
通过遍历__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)
Run Code Online (Sandbox Code Playgroud)现在,为了使无效,我仅调用myobject.invalidate("foo_group")
。
如果你不想使用try
and except
,也不想写更少的行,你可以使用:
if (hasattr(obj, "expensive_property")):
delattr(obj, "expensive_property")
Run Code Online (Sandbox Code Playgroud)
或者:
if (hasattr(obj, "expensive_property")):
del obj.expensive_property
Run Code Online (Sandbox Code Playgroud)
它将删除缓存的属性,并在下次访问时再次计算。
归档时间: |
|
查看次数: |
8973 次 |
最近记录: |