app/django/db/models/loading.py
changeset 323 ff1a9aa48cfd
parent 54 03e267d67478
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
     1 "Utilities for loading models and the modules that contain them."
     1 "Utilities for loading models and the modules that contain them."
     2 
     2 
     3 from django.conf import settings
     3 from django.conf import settings
     4 from django.core.exceptions import ImproperlyConfigured
     4 from django.core.exceptions import ImproperlyConfigured
       
     5 from django.utils.datastructures import SortedDict
       
     6 
     5 import sys
     7 import sys
     6 import os
     8 import os
     7 import threading
     9 import threading
     8 
    10 
     9 __all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models',
    11 __all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models',
    16     """
    18     """
    17     # Use the Borg pattern to share state between all instances. Details at
    19     # Use the Borg pattern to share state between all instances. Details at
    18     # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66531.
    20     # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66531.
    19     __shared_state = dict(
    21     __shared_state = dict(
    20         # Keys of app_store are the model modules for each application.
    22         # Keys of app_store are the model modules for each application.
    21         app_store = {},
    23         app_store = SortedDict(),
    22 
    24 
    23         # Mapping of app_labels to a dictionary of model names to model code.
    25         # Mapping of app_labels to a dictionary of model names to model code.
    24         app_models = {},
    26         app_models = SortedDict(),
    25 
    27 
    26         # Mapping of app_labels to errors raised when trying to import the app.
    28         # Mapping of app_labels to errors raised when trying to import the app.
    27         app_errors = {},
    29         app_errors = {},
    28 
    30 
    29         # -- Everything below here is only used when populating the cache --
    31         # -- Everything below here is only used when populating the cache --
   131         Given a module containing models, returns a list of the models.
   133         Given a module containing models, returns a list of the models.
   132         Otherwise returns a list of all installed models.
   134         Otherwise returns a list of all installed models.
   133         """
   135         """
   134         self._populate()
   136         self._populate()
   135         if app_mod:
   137         if app_mod:
   136             return self.app_models.get(app_mod.__name__.split('.')[-2], {}).values()
   138             return self.app_models.get(app_mod.__name__.split('.')[-2], SortedDict()).values()
   137         else:
   139         else:
   138             model_list = []
   140             model_list = []
   139             for app_entry in self.app_models.itervalues():
   141             for app_entry in self.app_models.itervalues():
   140                 model_list.extend(app_entry.values())
   142                 model_list.extend(app_entry.values())
   141             return model_list
   143             return model_list
   147 
   149 
   148         Returns None if no model is found.
   150         Returns None if no model is found.
   149         """
   151         """
   150         if seed_cache:
   152         if seed_cache:
   151             self._populate()
   153             self._populate()
   152         return self.app_models.get(app_label, {}).get(model_name.lower())
   154         return self.app_models.get(app_label, SortedDict()).get(model_name.lower())
   153 
   155 
   154     def register_models(self, app_label, *models):
   156     def register_models(self, app_label, *models):
   155         """
   157         """
   156         Register a set of models as belonging to an app.
   158         Register a set of models as belonging to an app.
   157         """
   159         """
   158         for model in models:
   160         for model in models:
   159             # Store as 'name: model' pair in a dictionary
   161             # Store as 'name: model' pair in a dictionary
   160             # in the _app_models dictionary
   162             # in the app_models dictionary
   161             model_name = model._meta.object_name.lower()
   163             model_name = model._meta.object_name.lower()
   162             model_dict = self.app_models.setdefault(app_label, {})
   164             model_dict = self.app_models.setdefault(app_label, SortedDict())
   163             if model_name in model_dict:
   165             if model_name in model_dict:
   164                 # The same model may be imported via different paths (e.g.
   166                 # The same model may be imported via different paths (e.g.
   165                 # appname.models and project.appname.models). We use the source
   167                 # appname.models and project.appname.models). We use the source
   166                 # filename as a means to detect identity.
   168                 # filename as a means to detect identity.
   167                 fname1 = os.path.abspath(sys.modules[model.__module__].__file__)
   169                 fname1 = os.path.abspath(sys.modules[model.__module__].__file__)