Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merged Apps.populate_apps() and populate_models().

After the recent series of refactorings, there's no reason to keep
two distinct methods.

Refs #21681.
  • Loading branch information...
commit 1c242a297b5b1857d76cab9b24f9f1d3b7f5240d 1 parent 966de84
@aaugustin aaugustin authored
View
3  django/__init__.py
@@ -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)
View
3  django/apps/base.py
@@ -152,8 +152,7 @@ def import_models(self, all_models):
# 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):
View
78 django/apps/registry.py
@@ -41,43 +41,39 @@ def __init__(self, installed_apps=()):
# 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 @@ def populate_apps(self, installed_apps=None):
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 @@ def check_ready(self):
"""
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 @@ def set_installed_apps(self, installed):
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):
View
3  django/core/management/__init__.py
@@ -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]
Please sign in to comment.
Something went wrong with that request. Please try again.