Simplified Apps.get_model and added AppConfig.get_model.

Documented them as public APIs.
This commit is contained in:
Aymeric Augustin 2013-12-28 14:41:11 +01:00
parent 81354b82bf
commit 54790e669d
3 changed files with 46 additions and 14 deletions

View File

@ -109,6 +109,23 @@ class AppConfig(object):
# Entry is a path to an app module.
return cls(entry, module)
def get_model(self, model_name):
"""
Returns the model with the given case-insensitive model_name.
Raises LookupError if no model exists with this name.
This method assumes that apps.populate_models() has run.
"""
if self.models is None:
raise LookupError(
"App '%s' doesn't have any models." % self.label)
try:
return self.models[model_name.lower()]
except KeyError:
raise LookupError(
"App '%s' doesn't have a '%s' model." % (self.label, model_name))
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.

View File

@ -185,7 +185,7 @@ class Apps(object):
if app_config is None:
raise LookupError("No installed app with label '%s'." % app_label)
if only_with_models_module and app_config.models_module is None:
raise LookupError("App with label '%s' doesn't have a models module." % app_label)
raise LookupError("App '%s' doesn't have a models module." % app_label)
return app_config
# This method is performance-critical at least for Django's test suite.
@ -242,21 +242,20 @@ class Apps(object):
)
return model_list
def get_model(self, app_label, model_name, only_installed=True):
def get_model(self, app_label, model_name):
"""
Returns the model matching the given app_label and case-insensitive
model_name.
Returns the model matching the given app_label and model_name.
Returns None if no model is found.
model_name is case-insensitive.
Returns None if no application exists with this label, or no model
exists with this name in the application.
"""
if not self.master:
only_installed = False
self.populate_models()
if only_installed:
app_config = self.app_configs.get(app_label)
if app_config is None:
return None
return self.all_models[app_label].get(model_name.lower())
try:
return self.get_app_config(app_label).get_model(model_name.lower())
except LookupError:
return None
def register_model(self, app_label, model):
# Since this method is called when models are imported, it cannot
@ -286,10 +285,11 @@ class Apps(object):
def get_registered_model(self, app_label, model_name):
"""
Returns the model class if one is registered and None otherwise.
Similar to get_model(), but doesn't require that an app exists with
the given app_label.
It's safe to call this method at import time, even while the registry
is being populated. It returns False for models that aren't loaded yet.
is being populated. It returns None for models that aren't loaded yet.
"""
return self.all_models[app_label].get(model_name.lower())

View File

@ -153,6 +153,15 @@ Read-only attributes
It may be ``None`` if the application doesn't contain a ``models`` module.
Methods
-------
.. method:: AppConfig.get_model(model_name)
Returns the :class:`~django.db.models.Model` with the given
``model_name``. Raises :exc:`~exceptions.LookupError` if no such model
exists. ``model_name`` is case-insensitive.
Application registry
====================
@ -189,3 +198,9 @@ Application registry
Unlike :meth:`~django.apps.apps.get_app_config`, this method can be called
safely at import time. If the registry is still being populated, it may
return ``False``, even though the app will become available later.
.. method:: apps.get_model(app_label, model_name)
Returns the :class:`~django.db.models.Model` with the given ``app_label``
and ``model_name``. Returns ``None`` if no such application or model
exists. ``model_name`` is case-insensitive.