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.
This commit is contained in:
parent
fd748c42a9
commit
625cd5bcb3
|
@ -155,13 +155,16 @@ class AppConfig(object):
|
||||||
# Entry is a path to an app config class.
|
# Entry is a path to an app config class.
|
||||||
return cls(app_name, app_module)
|
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.
|
Returns the model with the given case-insensitive model_name.
|
||||||
|
|
||||||
Raises LookupError if no model exists with this 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:
|
try:
|
||||||
return self.models[model_name.lower()]
|
return self.models[model_name.lower()]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|
|
@ -177,7 +177,7 @@ class Apps(object):
|
||||||
result.extend(list(app_config.get_models(include_auto_created, include_swapped)))
|
result.extend(list(app_config.get_models(include_auto_created, include_swapped)))
|
||||||
return result
|
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.
|
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
|
model exists with this name in the application. Raises ValueError if
|
||||||
called with a single argument that doesn't contain exactly one dot.
|
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:
|
if model_name is None:
|
||||||
app_label, model_name = app_label.split('.')
|
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):
|
def register_model(self, app_label, model):
|
||||||
# Since this method is called when models are imported, it cannot
|
# Since this method is called when models are imported, it cannot
|
||||||
|
|
|
@ -229,14 +229,20 @@ Methods
|
||||||
|
|
||||||
Requires the app registry to be fully populated.
|
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
|
Returns the :class:`~django.db.models.Model` with the given
|
||||||
``model_name``. ``model_name`` is case-insensitive.
|
``model_name``. ``model_name`` is case-insensitive.
|
||||||
|
|
||||||
Raises :exc:`LookupError` if no such model exists in this application.
|
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()
|
.. method:: AppConfig.ready()
|
||||||
|
|
||||||
|
@ -341,7 +347,7 @@ Application registry
|
||||||
Checks whether an application with the given name exists in the 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'``.
|
``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``
|
Returns the :class:`~django.db.models.Model` with the given ``app_label``
|
||||||
and ``model_name``. As a shortcut, this method also accepts a single
|
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
|
:exc:`ValueError` when called with a single argument that doesn't contain
|
||||||
exactly one dot.
|
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:
|
.. _app-loading-process:
|
||||||
|
|
||||||
Initialization process
|
Initialization process
|
||||||
|
|
|
@ -584,7 +584,8 @@ Miscellaneous
|
||||||
:exc:`~django.core.exceptions.AppRegistryNotReady` if they're called before
|
:exc:`~django.core.exceptions.AppRegistryNotReady` if they're called before
|
||||||
models of all applications have been loaded. Previously they only required
|
models of all applications have been loaded. Previously they only required
|
||||||
the target application's models to be loaded and thus could return models
|
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:
|
.. _deprecated-features-1.11:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue