1
0
mirror of https://github.com/django/django.git synced 2025-10-26 07:06:08 +00:00

Fixed #21711 -- Enforced unicity of model names.

This commit is contained in:
Aymeric Augustin
2014-01-05 09:32:22 +01:00
parent f5f7617167
commit f630373b92
4 changed files with 24 additions and 23 deletions

View File

@@ -185,7 +185,6 @@ class Apps(object):
# call get_app_config().
model_name = model._meta.model_name
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." %

View File

@@ -162,12 +162,6 @@ class ModelBase(type):
new_class._default_manager = new_class._default_manager._copy_to_model(new_class)
new_class._base_manager = new_class._base_manager._copy_to_model(new_class)
# Bail out early if we have already created this class.
try:
return new_class._meta.apps.get_registered_model(new_class._meta.app_label, name)
except LookupError:
pass
# Add all attributes to the class.
for obj_name, obj in attrs.items():
new_class.add_to_class(obj_name, obj)
@@ -285,13 +279,8 @@ class ModelBase(type):
return new_class
new_class._prepare()
new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
# Because of the way imports happen (recursively), we may or may not be
# the first time this model tries to register with the framework. There
# should only be one class for each model, so we always return the
# registered version.
return new_class._meta.apps.get_registered_model(new_class._meta.app_label, name)
return new_class
def copy_managers(cls, base_managers):
# This is in-place sorting of an Options attribute, but that's fine.

View File

@@ -7,6 +7,7 @@ circular import difficulties.
"""
from __future__ import unicode_literals
from django.apps import apps
from django.db.backends import utils
from django.utils import six
from django.utils import tree
@@ -185,22 +186,28 @@ def deferred_class_factory(model, attrs):
being replaced with DeferredAttribute objects. The "pk_value" ties the
deferred attributes to a particular instance of the model.
"""
class Meta:
proxy = True
app_label = model._meta.app_label
# The app registry wants a unique name for each model, otherwise the new
# class won't be created (we get an old one back). Therefore, we generate
# class won't be created (we get an exception). Therefore, we generate
# the name using the passed in attrs. It's OK to reuse an existing class
# object if the attrs are identical.
name = "%s_Deferred_%s" % (model.__name__, '_'.join(sorted(list(attrs))))
name = utils.truncate_name(name, 80, 32)
overrides = dict((attr, DeferredAttribute(attr, model)) for attr in attrs)
overrides["Meta"] = Meta
overrides["__module__"] = model.__module__
overrides["_deferred"] = True
return type(str(name), (model,), overrides)
try:
return apps.get_model(model._meta.app_label, name)
except LookupError:
class Meta:
proxy = True
app_label = model._meta.app_label
overrides = dict((attr, DeferredAttribute(attr, model)) for attr in attrs)
overrides["Meta"] = Meta
overrides["__module__"] = model.__module__
overrides["_deferred"] = True
return type(str(name), (model,), overrides)
# The above function is also used to unpickle model instances with deferred
# fields.