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__) |