summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2016-05-03 12:21:54 +0200
committerTim Graham <timograham@gmail.com>2016-10-28 19:08:57 -0400
commit625cd5bcb315154ed28061fefaf639aff54da7c2 (patch)
tree1565bba217e20110aaccd4abedfdcea90ddd534d
parentfd748c42a96213ebc0a18cc661ecb1abaadabcca (diff)
Added require_ready argument to get_model methods.
This allows bringing back the behavior of Django < 1.7. Also fixed the check for the app registry being ready in AppConfig.get_model(s), which was inconsistent with the equivalent check in Apps.get_model(s). That part is a backwards-incompatible change.
-rw-r--r--django/apps/config.py7
-rw-r--r--django/apps/registry.py16
-rw-r--r--docs/ref/applications.txt32
-rw-r--r--docs/releases/1.11.txt3
4 files changed, 49 insertions, 9 deletions
diff --git a/django/apps/config.py b/django/apps/config.py
index 72c5121411..14925cd1ce 100644
--- a/django/apps/config.py
+++ b/django/apps/config.py
@@ -155,13 +155,16 @@ class AppConfig(object):
# Entry is a path to an app config class.
return cls(app_name, app_module)
- def get_model(self, model_name):
+ def get_model(self, model_name, require_ready=True):
"""
Returns the model with the given case-insensitive model_name.
Raises LookupError if no model exists with this name.
"""
- self.apps.check_models_ready()
+ if require_ready:
+ self.apps.check_models_ready()
+ else:
+ self.apps.check_apps_ready()
try:
return self.models[model_name.lower()]
except KeyError:
diff --git a/django/apps/registry.py b/django/apps/registry.py
index adf6cbf753..48694d0f2c 100644
--- a/django/apps/registry.py
+++ b/django/apps/registry.py
@@ -177,7 +177,7 @@ class Apps(object):
result.extend(list(app_config.get_models(include_auto_created, include_swapped)))
return result
- def get_model(self, app_label, model_name=None):
+ def get_model(self, app_label, model_name=None, require_ready=True):
"""
Returns the model matching the given app_label and model_name.
@@ -190,10 +190,20 @@ class Apps(object):
model exists with this name in the application. Raises ValueError if
called with a single argument that doesn't contain exactly one dot.
"""
- self.check_models_ready()
+ if require_ready:
+ self.check_models_ready()
+ else:
+ self.check_apps_ready()
+
if model_name is None:
app_label, model_name = app_label.split('.')
- return self.get_app_config(app_label).get_model(model_name.lower())
+
+ app_config = self.get_app_config(app_label)
+
+ if not require_ready and app_config.models is None:
+ app_config.import_models()
+
+ return app_config.get_model(model_name, require_ready=require_ready)
def register_model(self, app_label, model):
# Since this method is called when models are imported, it cannot
diff --git a/docs/ref/applications.txt b/docs/ref/applications.txt
index 110e5e867d..149312aafd 100644
--- a/docs/ref/applications.txt
+++ b/docs/ref/applications.txt
@@ -229,14 +229,20 @@ Methods
Requires the app registry to be fully populated.
-.. method:: AppConfig.get_model(model_name)
+.. method:: AppConfig.get_model(model_name, require_ready=True)
Returns the :class:`~django.db.models.Model` with the given
``model_name``. ``model_name`` is case-insensitive.
Raises :exc:`LookupError` if no such model exists in this application.
- Requires the app registry to be fully populated.
+ Requires the app registry to be fully populated unless the
+ ``require_ready`` argument is set to ``False``. ``require_ready`` behaves
+ exactly as in :meth:`apps.get_model()`.
+
+ .. versionadded:: 1.11
+
+ The ``require_ready`` keyword argument was added.
.. method:: AppConfig.ready()
@@ -341,7 +347,7 @@ Application registry
Checks whether an application with the given name exists in the registry.
``app_name`` is the full name of the app, e.g. ``'django.contrib.admin'``.
-.. method:: apps.get_model(app_label, model_name)
+.. method:: apps.get_model(app_label, model_name, require_ready=True)
Returns the :class:`~django.db.models.Model` with the given ``app_label``
and ``model_name``. As a shortcut, this method also accepts a single
@@ -352,6 +358,26 @@ Application registry
:exc:`ValueError` when called with a single argument that doesn't contain
exactly one dot.
+ Requires the app registry to be fully populated unless the
+ ``require_ready`` argument is set to ``False``.
+
+ Setting ``require_ready`` to ``False`` allows looking up models
+ :ref:`while the app registry is being populated <app-loading-process>`,
+ specifically during the second phase where it imports models. Then
+ ``get_model()`` has the same effect as importing the model. The main use
+ case is to configure model classes with settings, such as
+ :setting:`AUTH_USER_MODEL`.
+
+ When ``require_ready`` is ``False``, ``get_model()`` returns a model class
+ that may not be fully functional (reverse accessors may be missing, for
+ example) until the app registry is fully populated. For this reason, it's
+ best to leave ``require_ready`` to the default value of ``True`` whenever
+ possible.
+
+ .. versionadded:: 1.11
+
+ The ``require_ready`` keyword argument was added.
+
.. _app-loading-process:
Initialization process
diff --git a/docs/releases/1.11.txt b/docs/releases/1.11.txt
index 8fd0795d67..7886d84a3b 100644
--- a/docs/releases/1.11.txt
+++ b/docs/releases/1.11.txt
@@ -584,7 +584,8 @@ Miscellaneous
:exc:`~django.core.exceptions.AppRegistryNotReady` if they're called before
models of all applications have been loaded. Previously they only required
the target application's models to be loaded and thus could return models
- without all their relations set up.
+ without all their relations set up. If you need the old behavior of
+ ``get_model()``, set the ``require_ready`` argument to ``False``.
.. _deprecated-features-1.11: