summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2013-01-29 00:28:09 -0500
committerAymeric Augustin <aymeric.augustin@m4x.org>2013-02-24 17:32:34 +0100
commit6b03179e126d4df01623dccc162c1579f349e41e (patch)
treeeb42a64785e44a2543c891b98087c36324180698 /django
parente369dc28075b4331c125494fe7bd73855d73a0ce (diff)
Fixed #19688 -- Allow model subclassing with a custom metaclass using six.with_metaclass
Diffstat (limited to 'django')
-rw-r--r--django/db/models/base.py13
1 files changed, 11 insertions, 2 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 5f058654bf..8eb4048365 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -58,12 +58,21 @@ class ModelBase(type):
"""
def __new__(cls, name, bases, attrs):
super_new = super(ModelBase, cls).__new__
+
# six.with_metaclass() inserts an extra class called 'NewBase' in the
- # inheritance tree: Model -> NewBase -> object. Ignore this class.
+ # inheritance tree: Model -> NewBase -> object. But the initialization
+ # should be executed only once for a given model class.
+
+ # attrs will never be empty for classes declared in the standard way
+ # (ie. with the `class` keyword). This is quite robust.
+ if name == 'NewBase' and attrs == {}:
+ return super_new(cls, name, bases, attrs)
+
+ # Also ensure initialization is only performed for subclasses of Model
+ # (excluding Model class itself).
parents = [b for b in bases if isinstance(b, ModelBase) and
not (b.__name__ == 'NewBase' and b.__mro__ == (b, object))]
if not parents:
- # If this isn't a subclass of Model, don't do anything special.
return super_new(cls, name, bases, attrs)
# Create the class.