diff options
| author | Sergey Fedoseev <fedoseev.sergey@gmail.com> | 2018-12-23 04:11:24 +0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2018-12-22 18:11:24 -0500 |
| commit | a68ea231012434b522ce45c513d84add516afa60 (patch) | |
| tree | 2ee6b2653eb8a91c6cbf840494bc8a5640e9a2a9 /django | |
| parent | ce8b65ac5e8e20912c36ab5c714ddf11de3b664c (diff) | |
Fixed #29970, #30041 -- Made ModelBase.__new__() pass attrs without contribute_to_class() to type.__new__().
Diffstat (limited to 'django')
| -rw-r--r-- | django/db/models/base.py | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py index b57726fbcf..b55c5a32b1 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -58,6 +58,11 @@ def subclass_exception(name, bases, module, attached_to): }) +def _has_contribute_to_class(value): + # Only call contribute_to_class() if it's bound. + return not inspect.isclass(value) and hasattr(value, 'contribute_to_class') + + class ModelBase(type): """Metaclass for all models.""" def __new__(cls, name, bases, attrs, **kwargs): @@ -75,8 +80,15 @@ class ModelBase(type): classcell = attrs.pop('__classcell__', None) if classcell is not None: new_attrs['__classcell__'] = classcell - new_class = super_new(cls, name, bases, new_attrs, **kwargs) attr_meta = attrs.pop('Meta', None) + # Pass all attrs without a (Django-specific) contribute_to_class() + # method to type.__new__() so that they're properly initialized + # (i.e. __set_name__()). + for obj_name, obj in list(attrs.items()): + if not _has_contribute_to_class(obj): + new_attrs[obj_name] = attrs.pop(obj_name) + new_class = super_new(cls, name, bases, new_attrs, **kwargs) + abstract = getattr(attr_meta, 'abstract', False) meta = attr_meta or getattr(new_class, 'Meta', None) base_meta = getattr(new_class, '_meta', None) @@ -300,8 +312,7 @@ class ModelBase(type): return new_class def add_to_class(cls, name, value): - # We should call the contribute_to_class method only if it's bound - if not inspect.isclass(value) and hasattr(value, 'contribute_to_class'): + if _has_contribute_to_class(value): value.contribute_to_class(cls, name) else: setattr(cls, name, value) |
