惰性加载是一种延迟计算的技术,当只有真正需要使用结果的时候才会去计算。Django提供了两种惰性加载模块,分别是lazy和LazyObject,前者主要针对可以调用的对象,延迟函数的调用;后者针对类,延迟类的实例化。
一、LazyObject
如果想要让某个类有延迟实例化的功能,必须做两件事情:
- 1)继承LazyObject;
- 2)实现_setup方法。
例子:
# 有延迟实例化需求的类DemoObject
class DemoObject(object):
def __init__(self):
self.title = 'just a demo'
def test(self):
print(123)
# 因为继承了LazyObject,所以DemoLazyObject有延迟实例化的功能
class DemoLazyObject(LazyObject):
# 子类需要重新实现_setup方法,该方法实例化类DemoObject,并把生成的对象赋给_wrapped。
def _setup(self):
self._wrapped = DemoObject()
# 实例化类DemoLazyObject,生成对象a_demo,此时并没有实际实例化类DemoObject。
a_demo = DemoLazyObject()
# 调用a_demo.title或a_demo.test()时候,会触发类DemoObject的实例化
print(a_demo.title)
django默认的文件存储类:
def get_storage_class(import_path=None):
return import_string(import_path or settings.DEFAULT_FILE_STORAGE)
class DefaultStorage(LazyObject):
def _setup(self):
self._wrapped = get_storage_class()()
default_storage = DefaultStorage()
存储后端:
ACCOUNT_STORAGE_BACKEND = {
'ENGINE': 'accounts.backends.VaultBackend',
'CONFIG': {
'url': CONFIG.VAULT_URL,
'token': CONFIG.VAULT_TOKEN,
'engine': CONFIG.VAULT_ENGINE,
'key': CONFIG.VAULT_KEY,
}
}
def get_account_storage():
config = settings.ACCOUNT_STORAGE_BACKEND
engine_class = import_string(config['ENGINE'])
s = engine_class(**config['CONFIG'])
return s
class Storage(LazyObject):
def _setup(self):
self._wrapped = get_account_storage()
storage = Storage()
二、lazy
from django.utils.functional import lazy
class OrgViewSet(mixins.ListModelMixin,
GenericViewSet):
filter_backends = []
queryset = lazy(AccountMicroApi.tree_org, list)()
serializer_class = OrgSerializer