"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