diff options
| author | Simon Charette <charette.s@gmail.com> | 2013-01-29 00:28:09 -0500 |
|---|---|---|
| committer | Aymeric Augustin <aymeric.augustin@m4x.org> | 2013-02-24 17:32:34 +0100 |
| commit | 6b03179e126d4df01623dccc162c1579f349e41e (patch) | |
| tree | eb42a64785e44a2543c891b98087c36324180698 /django | |
| parent | e369dc28075b4331c125494fe7bd73855d73a0ce (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.py | 13 |
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. |
