diff options
| author | Andrew Godwin <andrew@aeracode.org> | 2014-03-04 12:33:51 -0800 |
|---|---|---|
| committer | Andrew Godwin <andrew@aeracode.org> | 2014-03-04 12:33:51 -0800 |
| commit | 8fcc0140d075688e7b0565dea225f4380fc638c4 (patch) | |
| tree | 40de7653b1fa36deb51d44d937376b2eb0984478 /django | |
| parent | 6fe22b30e007b7ac49eae48a53e7ba0a4ee79a4b (diff) | |
| parent | 6436f1fad9ce51f18735106ac75aeea3d6d1f310 (diff) | |
Merge pull request #2396 from loic/ticket21893
Fixed #21893 -- ModelState didn't account for MTI parents inherited from abstract models.
Diffstat (limited to 'django')
| -rw-r--r-- | django/db/migrations/state.py | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index 76fc42d368..90226221be 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -151,6 +151,23 @@ class ModelState(object): options[name] = set(normalize_together(it)) else: options[name] = model._meta.original_attrs[name] + + def flatten_bases(model): + bases = [] + for base in model.__bases__: + if hasattr(base, "_meta") and base._meta.abstract: + bases.extend(flatten_bases(base)) + else: + bases.append(base) + return bases + + # We can't rely on __mro__ directly because we only want to flatten + # abstract models and not the whole tree. However by recursing on + # __bases__ we may end up with duplicates and ordering issues, we + # therefore discard any duplicates and reorder the bases according + # to their index in the MRO. + flattened_bases = sorted(set(flatten_bases(model)), key=lambda x:model.__mro__.index(x)) + # Make our record bases = tuple( ( @@ -158,12 +175,11 @@ class ModelState(object): if hasattr(base, "_meta") else base ) - for base in model.__bases__ - if (not hasattr(base, "_meta") or not base._meta.abstract) + for base in flattened_bases ) # Ensure at least one base inherits from models.Model if not any((isinstance(base, six.string_types) or issubclass(base, models.Model)) for base in bases): - bases = (models.Model, ) + bases = (models.Model,) return cls( model._meta.app_label, model._meta.object_name, |
