AppConfig既然是app的设置类,那么它有哪些属性?
通过__init__方法初始化的属性:
name: app的路径名 比如:django.contrib.admin
module: app的模块
通过继承AppConfig,定义类属性:
label:唯一的名字,默认是name的最后部分。比如:admin
verbose_name: 别名。默认为label.title( )
path:app的文件路径名。
django自动生成的属性:
models_module 对应app下面model模块
models 字典 {model_name: model_class}
然后再看看怎么在django中,设置自己的Appconfig:
Appconfig主要由它的类方法create(cls, entry)来实例化。
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)
整个导入流程如图所示:
可以看见有两个方法,一个是指明AppConfig的位置,模块名.类名。
# 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设置的一致性。