summaryrefslogtreecommitdiff
path: root/django/db/models/loading.py
diff options
context:
space:
mode:
Diffstat (limited to 'django/db/models/loading.py')
-rw-r--r--django/db/models/loading.py71
1 files changed, 71 insertions, 0 deletions
diff --git a/django/db/models/loading.py b/django/db/models/loading.py
new file mode 100644
index 0000000000..a9e0348f8e
--- /dev/null
+++ b/django/db/models/loading.py
@@ -0,0 +1,71 @@
+"Utilities for loading models and the modules that contain them."
+
+from django.conf import settings
+from django.core.exceptions import ImproperlyConfigured
+
+__all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models')
+
+_app_list = None # Cache of installed apps.
+_app_models = {} # Dictionary of models against app label
+ # Each value is a dictionary of model name: model class
+
+def get_apps():
+ "Returns a list of all installed modules that contain models."
+ global _app_list
+ if _app_list is not None:
+ return _app_list
+ _app_list = []
+ for app_name in settings.INSTALLED_APPS:
+ try:
+ _app_list.append(__import__(app_name, '', '', ['models']).models)
+ except (ImportError, AttributeError), e:
+ pass
+ return _app_list
+
+def get_app(app_label):
+ "Returns the module containing the models for the given app_label."
+ for app_name in settings.INSTALLED_APPS:
+ if app_label == app_name.split('.')[-1]:
+ return __import__(app_name, '', '', ['models']).models
+ raise ImproperlyConfigured, "App with label %s could not be found" % app_label
+
+def get_models(app_mod=None):
+ """
+ Given a module containing models, returns a list of the models. Otherwise
+ returns a list of all installed models.
+ """
+ app_list = get_apps() # Run get_apps() to populate the _app_list cache. Slightly hackish.
+ if app_mod:
+ return _app_models.get(app_mod.__name__.split('.')[-2], {}).values()
+ else:
+ model_list = []
+ for app_mod in app_list:
+ model_list.extend(get_models(app_mod))
+ return model_list
+
+def get_model(app_label, model_name):
+ """
+ Returns the model matching the given app_label and case-insensitive model_name.
+ Returns None if no model is found.
+ """
+ get_apps() # Run get_apps() to populate the _app_list cache. Slightly hackish.
+ try:
+ model_dict = _app_models[app_label]
+ except KeyError:
+ return None
+
+ try:
+ return model_dict[model_name.lower()]
+ except KeyError:
+ return None
+
+def register_models(app_label, *models):
+ """
+ Register a set of models as belonging to an app.
+ """
+ for model in models:
+ # Store as 'name: model' pair in a dictionary
+ # in the _app_models dictionary
+ model_name = model._meta.object_name.lower()
+ model_dict = _app_models.setdefault(app_label, {})
+ model_dict[model_name] = model