diff options
Diffstat (limited to 'django')
| -rw-r--r-- | django/core/management/commands/dumpdata.py | 2 | ||||
| -rw-r--r-- | django/core/serializers/__init__.py | 24 |
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 |
