上节咱们了解到,django
是如何进行处理请求的。python
那么 django
是如何进行 app
模块导入的。django
咱们所知道的。缓存
运行 django
应用分为 生产 和 本地开发 模式。一个经过 wsgi.py
来达到生产环境的运行,另外一个经过 manage.py runserver
来达到本地开发的运行。安全
可是咱们发现,这俩处入口均有 django.setup()
这一步。服务器
这俩点均有一些不一样之处,可是总体功能类似。app
咱们从 setup
这个功能函数提及。函数
def setup(set_prefix=True):
"""配置 logging 及应用注册。 """
# 这里的 apps 是一个单例模式,指向 django/apps/registry 下的 Apps 这个类
from django.apps import apps
from django.conf import settings
from django.urls import set_script_prefix
from django.utils.log import configure_logging
# 从 settings 文件下读取 LOGGING_CONFIG 配置日志文件
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
)
# 重点其实在这里,从 settings 文件获取 INSTALLED_APPS 配置
apps.populate(settings.INSTALLED_APPS)
复制代码
接下来,咱们移步到 populate
下的函数。url
def populate(self, installed_apps=None):
"""加载应用配置和模型 导入每一个应用程序模块,而后导入每一个模型模块。 它是线程安全的、幂等的,但不是可重入的。 """
if self.ready:
return
# 在初始化 WSGI 回调以前,在服务器上建立的线程可能会并行调用 `populate`
# 此处设置了线程锁
with self._lock:
if self.ready:
return
# RLock 防止其余线程进入这个部分。下面的比较和设置操做是原子性的。
if self.loading:
# Prevent reentrant calls to avoid running AppConfig.ready()
# methods twice.
raise RuntimeError("populate() isn't reentrant")
self.loading = True
# 阶段 1: 初始化 app 配置和导入 app 模型
for entry in installed_apps:
if isinstance(entry, AppConfig):
app_config = entry
else:
# 这里经过一个工厂方法创造出一个应用实例
app_config = AppConfig.create(entry)
if app_config.label in self.app_configs:
raise ImproperlyConfigured(
"Application labels aren't unique, "
"duplicates: %s" % app_config.label)
# 载入到 app_configs 配置
# key 为 应用标签,值为 app 实例
self.app_configs[app_config.label] = app_config
app_config.apps = self
# 检测重复的 app 名称,确保惟一性
counts = Counter(
app_config.name for app_config in self.app_configs.values())
duplicates = [
name for name, count in counts.most_common() if count > 1]
if duplicates:
raise ImproperlyConfigured(
"Application names aren't unique, "
"duplicates: %s" % ", ".join(duplicates))
# 设置应用加载完成标识位
self.apps_ready = True
# 阶段 2: 导入模型模块
for app_config in self.app_configs.values():
app_config.import_models()
# 清空缓存
self.clear_cache()
# 设置模型加载完成标识位
self.models_ready = True
# 阶段 3: 运行 app 下的 ready 方法(钩子方法)
for app_config in self.get_app_configs():
app_config.ready()
# 初始化完成
self.ready = True
复制代码
到此,咱们在 run
一个 django 应用的时候,会调用 django
的 setup
方法,主要是载入全部的应用和模型。spa