Merged Apps.populate_apps() and populate_models().
After the recent series of refactorings, there's no reason to keep two distinct methods. Refs #21681.
This commit is contained in:
parent
966de84973
commit
1c242a297b
|
@ -13,5 +13,4 @@ def setup():
|
|||
# INSTALLED_APPS or any other setting) and populate the app registry.
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
apps.populate_apps(settings.INSTALLED_APPS)
|
||||
apps.populate_models()
|
||||
apps.populate(settings.INSTALLED_APPS)
|
||||
|
|
|
@ -152,8 +152,7 @@ class AppConfig(object):
|
|||
# Dictionary of models for this app, primarily maintained in the
|
||||
# 'all_models' attribute of the Apps this AppConfig is attached to.
|
||||
# Injected as a parameter because it gets populated when models are
|
||||
# imported, which might happen before populate_models() runs (or at
|
||||
# least used to).
|
||||
# imported, which might happen before populate() imports models.
|
||||
self.models = all_models
|
||||
|
||||
if module_has_submodule(self.module, MODELS_MODULE_NAME):
|
||||
|
|
|
@ -41,43 +41,39 @@ class Apps(object):
|
|||
# set_available_apps and set_installed_apps.
|
||||
self.stored_app_configs = []
|
||||
|
||||
# Internal flags used when populating the registry.
|
||||
self._apps_loaded = False
|
||||
self._models_loaded = False
|
||||
# Whether the registry is populated.
|
||||
self.ready = False
|
||||
|
||||
# Pending lookups for lazy relations.
|
||||
self._pending_lookups = {}
|
||||
|
||||
# Populate apps and models, unless it's the master registry.
|
||||
if installed_apps is not None:
|
||||
self.populate_apps(installed_apps)
|
||||
self.populate_models()
|
||||
self.populate(installed_apps)
|
||||
|
||||
def populate_apps(self, installed_apps=None):
|
||||
def populate(self, installed_apps=None):
|
||||
"""
|
||||
Populate app-related information.
|
||||
Loads application configurations and models.
|
||||
|
||||
This method imports each application module.
|
||||
This method imports each application module and then each model module.
|
||||
|
||||
It is thread safe and idempotent, but not reentrant.
|
||||
"""
|
||||
if self._apps_loaded:
|
||||
if self.ready:
|
||||
return
|
||||
# Since populate_apps() may be a side effect of imports, and since
|
||||
# it will itself import modules, an ABBA deadlock between threads
|
||||
# would be possible if we didn't take the import lock. See #18251.
|
||||
# Since populate() may be a side effect of imports, and since it will
|
||||
# itself import modules, an ABBA deadlock between threads would be
|
||||
# possible if we didn't take the import lock. See #18251.
|
||||
with import_lock():
|
||||
if self._apps_loaded:
|
||||
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.
|
||||
if self.app_configs:
|
||||
raise RuntimeError("populate_apps() isn't reentrant")
|
||||
raise RuntimeError("populate() isn't reentrant")
|
||||
|
||||
# Application modules aren't expected to import anything, and
|
||||
# especially not other application modules, even indirectly.
|
||||
# Therefore we simply import them sequentially.
|
||||
# Load app configs and app modules.
|
||||
for entry in installed_apps:
|
||||
if isinstance(entry, AppConfig):
|
||||
app_config = entry
|
||||
|
@ -85,36 +81,13 @@ class Apps(object):
|
|||
app_config = AppConfig.create(entry)
|
||||
self.app_configs[app_config.label] = app_config
|
||||
|
||||
self.clear_cache()
|
||||
self._apps_loaded = True
|
||||
|
||||
def populate_models(self):
|
||||
"""
|
||||
Populate model-related information.
|
||||
|
||||
This method imports each models module.
|
||||
|
||||
It is thread safe, idempotent and reentrant.
|
||||
"""
|
||||
if self._models_loaded:
|
||||
return
|
||||
# Since populate_models() may be a side effect of imports, and since
|
||||
# it will itself import modules, an ABBA deadlock between threads
|
||||
# would be possible if we didn't take the import lock. See #18251.
|
||||
with import_lock():
|
||||
if self._models_loaded:
|
||||
return
|
||||
|
||||
if not self._apps_loaded:
|
||||
raise RuntimeError(
|
||||
"populate_models() must run after populate_apps()")
|
||||
|
||||
# Load models.
|
||||
for app_config in self.app_configs.values():
|
||||
all_models = self.all_models[app_config.label]
|
||||
app_config.import_models(all_models)
|
||||
|
||||
self.clear_cache()
|
||||
self._models_loaded = True
|
||||
self.ready = True
|
||||
|
||||
for app_config in self.get_app_configs():
|
||||
app_config.setup()
|
||||
|
@ -123,21 +96,11 @@ class Apps(object):
|
|||
"""
|
||||
Raises an exception if the registry isn't ready.
|
||||
"""
|
||||
if not self._models_loaded:
|
||||
if not self.ready:
|
||||
raise RuntimeError(
|
||||
"App registry isn't populated yet. "
|
||||
"Have you called django.setup()?")
|
||||
|
||||
@property
|
||||
def ready(self):
|
||||
"""
|
||||
Whether the registry is fully populated.
|
||||
|
||||
Useful for code that wants to cache the results of get_models() for
|
||||
themselves once it is safe to do so.
|
||||
"""
|
||||
return self._models_loaded # implies self._apps_loaded.
|
||||
|
||||
def get_app_configs(self, only_with_models_module=False):
|
||||
"""
|
||||
Imports applications and returns an iterable of app configs.
|
||||
|
@ -306,19 +269,16 @@ class Apps(object):
|
|||
self.check_ready()
|
||||
self.stored_app_configs.append(self.app_configs)
|
||||
self.app_configs = OrderedDict()
|
||||
self.ready = False
|
||||
self.clear_cache()
|
||||
self._apps_loaded = False
|
||||
self.populate_apps(installed)
|
||||
self._models_loaded = False
|
||||
self.populate_models()
|
||||
self.populate(installed)
|
||||
|
||||
def unset_installed_apps(self):
|
||||
"""
|
||||
Cancels a previous call to set_installed_apps().
|
||||
"""
|
||||
self.app_configs = self.stored_app_configs.pop()
|
||||
self._apps_loaded = True
|
||||
self._models_loaded = True
|
||||
self.ready = True
|
||||
self.clear_cache()
|
||||
|
||||
def clear_cache(self):
|
||||
|
|
|
@ -121,8 +121,7 @@ def get_commands():
|
|||
# avoid catching ImproperlyConfigured errors that aren't caused
|
||||
# by the absence of a settings module.
|
||||
from django.apps import apps
|
||||
apps.populate_apps(installed_apps)
|
||||
apps.populate_models()
|
||||
apps.populate(installed_apps)
|
||||
app_configs = apps.get_app_configs()
|
||||
app_names = [app_config.name for app_config in app_configs]
|
||||
|
||||
|
|
Loading…
Reference in New Issue