Fleshed out AppConfig objects.

Marginally improved creation of AppConfig stubs for non-installed apps.
This commit is contained in:
Aymeric Augustin 2013-12-12 23:33:09 +01:00
parent b55282b98b
commit c5eac3a2f6
2 changed files with 34 additions and 15 deletions

View File

@ -1,25 +1,46 @@
from collections import OrderedDict from collections import OrderedDict
from django.utils._os import upath
class AppConfig(object): class AppConfig(object):
""" """
Class representing a Django application and its configuration. Class representing a Django application and its configuration.
""" """
def __init__(self, label, models_module=None, installed=True): def __init__(self, name, app_module, models_module):
# Full Python path to the application eg. 'django.contrib.admin'.
# This is the value that appears in INSTALLED_APPS.
self.name = name
# Last component of the Python path to the application eg. 'admin'. # Last component of the Python path to the application eg. 'admin'.
self.label = label # This value must be unique across a Django project.
self.label = name.rpartition(".")[2]
# Root module eg. <module 'django.contrib.admin' from
# 'django/contrib/admin/__init__.pyc'>.
self.app_module = app_module
# Module containing models eg. <module 'django.contrib.admin.models' # Module containing models eg. <module 'django.contrib.admin.models'
# from 'django/contrib/admin/models.pyc'>. # from 'django/contrib/admin/models.pyc'>.
self.models_module = models_module self.models_module = models_module
# Mapping of lower case model names to model classes. # Mapping of lower case model names to model classes.
# Populated by AppCache.register_models().
self.models = OrderedDict() self.models = OrderedDict()
# Whether the app is in INSTALLED_APPS or was automatically created # Whether the app is in INSTALLED_APPS or was automatically created
# when one of its models was imported. # when one of its models was imported.
self.installed = installed self.installed = app_module is not None
# Filesystem path to the application directory eg.
# u'/usr/lib/python2.7/dist-packages/django/contrib/admin'.
# This is a unicode object on Python 2 and a str on Python 3.
self.path = upath(app_module.__path__[0]) if app_module is not None else None
@classmethod
def _stub(cls, label):
return cls(label, None, None)
def __repr__(self): def __repr__(self):
return '<AppConfig: %s>' % self.label return '<AppConfig: %s>' % self.label

View File

@ -133,16 +133,15 @@ class BaseAppCache(object):
raise raise
self.nesting_level -= 1 self.nesting_level -= 1
label = self._label_for(models_module)
try: app_config = AppConfig(
app_config = self.app_configs[label] name=app_name, app_module=app_module, models_module=models_module)
except KeyError: # If a stub config existed for this app, preserve models registry.
self.app_configs[label] = AppConfig( old_app_config = self.app_configs.get(app_config.label)
label=label, models_module=models_module) if old_app_config is not None:
else: app_config.models = old_app_config.models
if not app_config.installed: self.app_configs[app_config.label] = app_config
app_config.models_module = models_module
app_config.installed = True
return models_module return models_module
def app_cache_ready(self): def app_cache_ready(self):
@ -318,8 +317,7 @@ class BaseAppCache(object):
try: try:
app_config = self.app_configs[app_label] app_config = self.app_configs[app_label]
except KeyError: except KeyError:
app_config = AppConfig( app_config = AppConfig._stub(app_label)
label=app_label, installed=False)
self.app_configs[app_label] = app_config self.app_configs[app_label] = app_config
for model in models: for model in models:
# Add the model to the app_config's models dictionary. # Add the model to the app_config's models dictionary.