先了解下官方文檔的介紹
Django包含了一個已經安裝應用的注冊表,這個注冊表存儲着配置信息以及用來自省,同時也維護着可用模型的列表。
這個注冊表就是apps,位於django.apps下,本質上是一個django.apps.registry模塊下的一個Apps類的實例。
源碼面前見真相:

class Apps(object):
這是一個注冊表,存儲着已安裝應用的配置信息,同時也跟蹤着模型,例如提供reverse-relations。
初始化的主要屬性:
apps_configs:這是一個有順序的字典,將AppConfig實例的label標簽映射到已經安裝的entry(AppConfig)上。
主要方法:
populate(installded_app):載入應用的配置信息和模型,這個方法導入每個應用模塊然后是每個模型模塊,它是線程安全並且是冪等(任意多次執行所產生的影響均與一次執行的影響相同)的,但是不能重入(reentrant),簡單百度下,應該是不能進行遞歸調用的意思。
if self.ready: #該注冊表是否已經被填充 return # populate() might be called by two threads in parallel on servers # that create threads before initializing the WSGI callable.
# populate()在初始化WSGI調用之前,可能會被會創建線程的服務器上的兩個並行的線程調用。 with self._lock:
#_lock()為Theading.Lock()對象,在with上下文管理器中自動獲取鎖,處理過后,自動釋放鎖。 if self.ready: return # app_config should be pristine, otherwise the code below won't # guarantee that the order matches the order in INSTALLED_APPS.
# app_config應該是處於原始的狀態,否則下面的代碼將不能保證這個順序匹配INSTALLED_APPS中的順序。
if self.app_configs: raise RuntimeError("populate() isn't reentrant") # Phase 1: initialize app configs and import app modules. for entry in installed_apps:
# 迭代已安裝apps的每一項 if isinstance(entry, AppConfig): app_config = entry else:
# 若INSTALLED_APPS中配置的不是AppConfig類的Python路徑而是App模塊路徑,將會以工廠方式進行創建。 app_config = AppConfig.create(entry) if app_config.label in self.app_configs:
# 檢測app_config的唯一性。 raise ImproperlyConfigured( "Application labels aren't unique, " "duplicates: %s" % app_config.label) self.app_configs[app_config.label] = app_config # app_config.label屬性默認是由app_name獲取的。 app_config.apps = self #將注冊表賦給AppConfig類的apps屬性。 # Check for duplicate app names. 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 # Phase 2: import models modules.
# 導入模型模塊
for app_config in self.app_configs.values(): app_config.import_models() self.clear_cache() self.models_ready = True # Phase 3: run ready() methods of app configs.
# 運行apps configs的ready()方法。
for app_config in self.get_app_configs(): app_config.ready() self.ready = True
