AppConfig既然是app的設置類,那麼它有哪些屬性?
python
經過__init__方法初始化的屬性:django
name: app的路徑名 好比:django.contrib.admin module: app的模塊
經過繼承AppConfig,定義類屬性:app
label:惟一的名字,默認是name的最後部分。好比:admin verbose_name: 別名。默認爲label.title( ) path:app的文件路徑名。
django自動生成的屬性:
this
models_module 對應app下面model模塊 models 字典 {model_name: model_class}
而後再看看怎麼在django中,設置本身的Appconfig:code
Appconfig主要由它的類方法create(cls, entry)來實例化。orm
entry即爲setting中的INSTALLED_APPS的元素。繼承
@classmethod def create(cls, entry): """ Factory that creates an app config from an entry in INSTALLED_APPS. """ 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) 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. module = None mod_path, _, cls_name = entry.rpartition('.') # Raise the original exception when entry cannot be a path to an # app config class. if not mod_path: raise else: try: # If this works, the app module specifies an app config class. entry = module.default_app_config except AttributeError: # Otherwise, it simply uses the default app config class. return cls(entry, module) else: mod_path, _, cls_name = entry.rpartition('.') # If we're reaching this point, we must attempt to load the app config # class located at <mod_path>.<cls_name> # Avoid django.utils.module_loading.import_by_path because it # masks errors -- it reraises ImportError as ImproperlyConfigured. mod = import_module(mod_path) 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. app_module = import_module(app_name) # Entry is a path to an app config class. return cls(app_name, app_module)
整個導入流程如圖所示:ci
能夠看見有兩個方法,一個是指明AppConfig的位置,模塊名.類名。rem
# settings.py INSTALLED_APPS = ( ..., 'rock_n_roll.apps.RockNRollConfig', ... )
二是在模塊__init__.py文件中,聲明default_app_config屬性。default_app_config爲字符串,指定AppConfig的位置。字符串
引用官網的例子:
rock_n_roll是一個app。這是下面的app.py文件
# rock_n_roll/apps.py from django.apps import AppConfigclass RockNRollConfig(AppConfig): name = 'rock_n_roll' verbose_name = "Rock ’n’ roll"
# rock_n_roll/__init__.py default_app_config = 'rock_n_roll.apps.RockNRollConfig'
不過通常使用第二種比較多,由於這樣保證了INSTALLED_APPS設置的一致性。