現在、モデルクラスで@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
ありがとう
ドキュメンテーションとしてそれを削除してください says 。次のアクセス時に再計算されます。
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
進行中の開発のために大幅に編集...特定の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)
_
他のオブジェクトでは、新しい_cached_property.tag
_デコレータクラスメソッドを使用して、タグ付き_cached_property
_メソッドを定義します。
_@cached_property.tag("foo_group")
def foo(self):
return "foo"
_
新しいデコレーターを使用する私のオブジェクトで、インスタンス化されたオブジェクトのクラスの_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)
_
今、無効にするために、私は単にmyobject.invalidate("foo_group")
を呼び出します。
model.refresh_from_db()
が呼び出されたときにモデルのすべての_@cached_property
_プロパティを無効にするDjangoモデルミックスインを作成しました。キャッシュされたプロパティを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
Thomas Baden の答えに触発されました。