Skip to content

Instantly share code, notes, and snippets.

@loic
Created March 4, 2014 19:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loic/9353648 to your computer and use it in GitHub Desktop.
Save loic/9353648 to your computer and use it in GitHub Desktop.
diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py
index 79a4411..ad9fb07 100644
--- a/django/db/migrations/state.py
+++ b/django/db/migrations/state.py
@@ -1,3 +1,5 @@
+from collections import OrderedDict
+
from django.apps import AppConfig
from django.apps.registry import Apps
from django.db import models
@@ -151,6 +153,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(list(set(flatten_bases(model))), key=lambda x:model.__mro__.index(x))
+
# Make our record
bases = tuple(
(
@@ -158,8 +177,7 @@ 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):
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment