summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
Diffstat (limited to 'django')
-rw-r--r--django/core/management/commands/dumpdata.py2
-rw-r--r--django/core/serializers/__init__.py24
2 files changed, 18 insertions, 8 deletions
diff --git a/django/core/management/commands/dumpdata.py b/django/core/management/commands/dumpdata.py
index 2968f74805..247b0f20fd 100644
--- a/django/core/management/commands/dumpdata.py
+++ b/django/core/management/commands/dumpdata.py
@@ -144,7 +144,7 @@ class Command(BaseCommand):
Collate the objects to be serialized. If count_only is True, just
count the number of objects to be serialized.
"""
- models = serializers.sort_dependencies(app_list.items())
+ models = serializers.sort_dependencies(app_list.items(), allow_cycles=True)
for model in models:
if model in excluded_models:
continue
diff --git a/django/core/serializers/__init__.py b/django/core/serializers/__init__.py
index d0e504ade3..5e16a7560f 100644
--- a/django/core/serializers/__init__.py
+++ b/django/core/serializers/__init__.py
@@ -156,12 +156,15 @@ def _load_serializers():
_serializers = serializers
-def sort_dependencies(app_list):
+def sort_dependencies(app_list, allow_cycles=False):
"""Sort a list of (app_config, models) pairs into a single list of models.
The single list of models is sorted so that any model with a natural key
is serialized before a normal model, and any model with a natural key
dependency has it's dependencies serialized first.
+
+ If allow_cycles is True, return the best-effort ordering that will respect
+ most of dependencies but ignore some of them to break the cycles.
"""
# Process the list of models, and get the list of dependencies
model_dependencies = []
@@ -222,13 +225,20 @@ def sort_dependencies(app_list):
else:
skipped.append((model, deps))
if not changed:
- raise RuntimeError(
- "Can't resolve dependencies for %s in serialized app list." %
- ', '.join(
- model._meta.label
- for model, deps in sorted(skipped, key=lambda obj: obj[0].__name__)
+ if allow_cycles:
+ # If cycles are allowed, add the last skipped model and ignore
+ # its dependencies. This could be improved by some graph
+ # analysis to ignore as few dependencies as possible.
+ model, _ = skipped.pop()
+ model_list.append(model)
+ else:
+ raise RuntimeError(
+ "Can't resolve dependencies for %s in serialized app list."
+ % ', '.join(
+ model._meta.label
+ for model, deps in sorted(skipped, key=lambda obj: obj[0].__name__)
+ ),
)
- )
model_dependencies = skipped
return model_list