class AppConfig(object)
這個基類描述了一個Django應用以及它的配置信息。
屬性:
name:django應用的完整python路徑,eg.'django.contrib.admin',在初始化參數中由app_name參數指定。
module:django應用的根模塊,是一個模塊對象,eg.<module 'django.contrib.admin' from 'django/contrib/admin/__init__.pyc'>,也就是django應用所在的包,在我的理解下目錄下的__init__.py就是對Python包的抽象,在Python看來包也就是一個模塊。
apps:Apps注冊表的引用,該注冊表保存管理着這個AppConfig。當注冊表注冊這個AppConfig實例的時候,由注冊表進行設置。
label:
path:django應用的文件系統的路徑。eg.'usr/lib/python2.7/dist-packages/django/contrib/admin'。
models_module:包含models的模塊,也就是models.py文件,這是由import_models()設置,若沒有則為None。
models:映射小寫的模型名到模型類上。初始化的時候為None,避免在import_models運行前意外的訪問。
方法:
create:這是一個類方法,是一個工廠為INSTALLEDAPPS的一個條目創建一個app config,返回是cls(app_name,app_module),即該類的一個實例。
源碼:
def create(cls, entry): try: # If import_module succeeds, entry is a path to an app module, # which may specify an app config class with default_app_config. # Otherwise, entry is a path to an app config class or an error.
module = import_module(entry)
# entry可以是一個app模塊的路徑,也可以是一個app config類的路徑。
#首先用import_module方法導入App模塊,這個App模塊也許用default_app_config這變量指定了一個app config
#若導入成功話,這就是說entry是一個app模塊的路徑。 except ImportError: # Track that importing as an app module failed. If importing as an # app config class fails too, we'll trigger the ImportError again.
# 作為app模塊導入失敗后,如果嘗試作為app config類導入也失敗的話,觸發這個導入錯誤。 module = None mod_path, _, cls_name = entry.rpartition('.')
# 獲取這個config類的python模塊的python路徑。 # Raise the original exception when entry cannot be a path to an # app config class. if not mod_path: #這個python路徑不存在拋出錯誤。 raise else: try: # If this works, the app module specifies an app config class.
# 如果導入app模塊成功的話,接着就嘗試獲取這個app模塊的config配置。
entry = module.default_app_config except AttributeError: # Otherwise, it simply uses the default app config class.
沒有這個屬性將會簡單滴使用默認的app config類,返回AppConfig類的實例。
return cls(entry, module) else: mod_path, _, cls_name = entry.rpartition('.')
#如果存在,返回這個config類的python模塊點路徑。 # If we're reaching this point, we must attempt to load the app config # class located at <mod_path>.<cls_name>
mod = import_module(mod_path)
# 導入config類的模塊,並嘗試獲取這個App config這個類 try: cls = getattr(mod, cls_name)
except AttributeError: if module is None: # If importing as an app module failed, that error probably # contains the most informative traceback. Trigger it again. import_module(entry)
# 如果導入失敗,這主要用來獲取做為詳細的錯誤跟蹤。 else: raise # Check for obvious errors. (This check prevents duck typing, but # it could be removed if it became a problem in practice.) if not issubclass(cls, AppConfig): raise ImproperlyConfigured( "'%s' isn't a subclass of AppConfig." % entry) # Obtain app name here rather than in AppClass.__init__ to keep # all error checking for entries in INSTALLED_APPS in one place. try: app_name = cls.name except AttributeError: raise ImproperlyConfigured( "'%s' must supply a name attribute." % entry) # Ensure app_name points to a valid module. try: app_module = import_module(app_name) except ImportError: raise ImproperlyConfigured( "Cannot import '%s'. Check that '%s.%s.name' is correct." % ( app_name, mod_path, cls_name, ) ) # Entry is a path to an app config class. return cls(app_name, app_module)
Entry is a path to an app config class。本質上來說,因為根據源碼可知即使entry在INSTALLED_APPS是django應用模塊最后定位還是其中配置的AppConfig類。要配置一個應用,要子類化AppConfig 並將這個子類的路徑放在INSTALLED_APPS 中,調用get_app_config返回的是這個子類化的AppConfig。當INSTALLED_APPS 包含一個應用模塊的路徑后,Django 將在這個模塊中檢查一個default_app_config 變量。如果這個變量有定義,它應該是這個應用的AppConfig 子類的路徑,調用get_app_config返回的是這個子類化的AppConfig。如果沒有default_app_config,Django 將使用AppConfig 基類,調用get_app_config返回的是AppConfig基類。