上節咱們瞭解到,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