summaryrefslogtreecommitdiff
path: root/django/apps
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2013-12-27 23:03:03 +0100
committerAymeric Augustin <aymeric.augustin@m4x.org>2013-12-28 09:34:46 +0100
commitaff57793b46e108c6e48d5ce3b889bf90b513df9 (patch)
tree337ea34de977d56b2ca40eb4dd4c3d46d4671b93 /django/apps
parent3518e9ec1f23f0278aefea6738f9d49eb7d4fe52 (diff)
Simplified the implementation of register_model.
register_model is called exactly once in the entire Django code base, at the bottom of ModelBase.__new__: new_class._meta.apps.register_model(new_class._meta.app_label, new_class) ModelBase.__new__ exits prematurely 120 lines earlier (sigh) if a model with the same name is already registered: if new_class._meta.apps.get_registered_model(new_class._meta.app_label, name): return (This isn't the exact code, but it's equivalent.) apps.register_model and apps.get_registered_model are essentially a setter and a getter for apps.all_models, and apps.register_model is the only setter. As a consequence, new_class._meta.apps.all_models cannot change in-between. Considering that name == new_class.__name__, we can conclude that register_model(app_label, model) is always called with such arguments that get_registered_model(app_label, model.__name__) returns None. Considering that model._meta.model_name == model.__name__.lower(), and looking at the implementation of register_model and get_registered_model, this proves that self.all_models[app_label] doesn't contain model._meta.model_name in register_model, allowing us to simplify the implementation.
Diffstat (limited to 'django/apps')
-rw-r--r--django/apps/registry.py20
1 files changed, 7 insertions, 13 deletions
diff --git a/django/apps/registry.py b/django/apps/registry.py
index 8a25bad281..42affbbc13 100644
--- a/django/apps/registry.py
+++ b/django/apps/registry.py
@@ -261,19 +261,13 @@ class Apps(object):
# perform imports because of the risk of import loops. It mustn't
# call get_app_config().
model_name = model._meta.model_name
- models = self.all_models[app_label]
- if model_name in models:
- # The same model may be imported via different paths (e.g.
- # appname.models and project.appname.models). We use the source
- # filename as a means to detect identity.
- fname1 = os.path.abspath(upath(sys.modules[model.__module__].__file__))
- fname2 = os.path.abspath(upath(sys.modules[models[model_name].__module__].__file__))
- # Since the filename extension could be .py the first time and
- # .pyc or .pyo the second time, ignore the extension when
- # comparing.
- if os.path.splitext(fname1)[0] == os.path.splitext(fname2)[0]:
- return
- models[model_name] = model
+ app_models = self.all_models[app_label]
+ # Defensive check for extra safety.
+ if model_name in app_models:
+ raise RuntimeError(
+ "Conflicting '%s' models in application '%s': %s and %s." %
+ (model_name, app_label, app_models[model_name], model))
+ app_models[model_name] = model
self.get_models.cache_clear()
def has_app(self, app_name):