配置文件
settings.py
, 设置DJANGO_SETTINGS_MODULE
环境变量,调用django.setup()
启动
import os, sys
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyProject.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError("...") from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
def setup(set_prefix=True):
"""
Configure the settings (this happens as a side effect of accessing the
first setting), configure logging and populate the app registry.
Set the thread-local urlresolvers script prefix if `set_prefix` is True.
"""
from django.apps import apps
from django.conf import settings
from django.urls import set_script_prefix
from django.utils.log import configure_logging
configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
if set_prefix:
set_script_prefix(
'/' if settings.FORCE_SCRIPT_NAME is None else settings.FORCE_SCRIPT_NAME
)
apps.populate(settings.INSTALLED_APPS)
加载
DJANGO_SETTINGS_MODULE
环境变量,初始化django.conf.settings类
class LazySettings(LazyObject):
def _setup(self, name=None):
settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
if not settings_module:
desc = ("setting %s" % name) if name else "settings"
raise ImproperlyConfigured("....")
self._wrapped = Settings(settings_module)
def __getattr__(self, name):
"""Return the value of a setting and cache it in self.__dict__."""
if self._wrapped is empty:
self._setup(name)
val = getattr(self._wrapped, name)
self.__dict__[name] = val
return val
class Settings:
def __init__(self, settings_module):
pass # 加载配置
根据settings.py文件中注册的
INSTALLED_APPS
列表,遍历各个App模块下的Models.
apps.populate(settings.INSTALLED_APPS)
django中延迟加载,一个类只在第一次使用时才初始化。继承LazyObject的子类必须实现
_setup()
方法。
def new_method_proxy(func):
def inner(self, *args):
if self._wrapped is empty:
self._setup()
return func(self._wrapped, *args)
return inner
class LazyObject:
def __init__(self):
# Note: if a subclass overrides __init__(), it will likely need to
# override __copy__() and __deepcopy__() as well.
self._wrapped = empty
__getattr__ = new_method_proxy(getattr)
def _setup(self):
""" Must be implemented by subclasses to initialize the wrapped object. """
raise NotImplementedError('subclasses of LazyObject must provide a _setup() method')
如下,当第一次调用t.name时,先后调用 LazyObject.__getattr__
、 LazyObject.new_method_proxy()
、self._setup()
、 Test.__init__()
、 getattr(self._wrapped, *args)
;之后再取值不会再调用self._setup()
from django.utils.functional import LazyObject
class Test(object):
def __init__(self):
self.name = 'Hello'
class LazyTest(LazyObject):
def _setup(self):
self._wrapped = Test()
t = LazyTest() # 还没真正实例化
print(t.name) # 触发加载
Promiss代理类的基类,用于识别代码中需要惰性加载的对象。
from django.utils.functional import lazy
def lazy_func(text):
return text.title()
# 获得一个惰性代理对象lazy_wraper
lazy_wraper = lazy(lazy_func, str)
# 注意,此时虽然调用了惰性函数,但并不会直接去调用lazy_func函数
res = lazy_wraper('hello world')
# 打印结果时,才会去实际调用lazy_func。
print(res)