summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2024-01-31 16:10:05 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2024-01-31 16:10:50 +0100
commit7453d6a80792e3f811fc662b8b25fdcbc5ea7eb3 (patch)
treeaf200ac40bea58431ea91c2efd6698e21ae70ddd
parent2822cafa3c38c8352eacb82aad27cc29338d8ad7 (diff)
[5.0.x] Fixed #35159 -- Fixed dumpdata crash when base querysets use prefetch_related().
Regression in 139135627650ed6aaaf4c755b82c3bd43f2b8f51 following deprecation in edbf930287cb72e9afab1f7208c24b1146b0c4ec. Thanks Andrea F for the report. Backport of 38eaf2f21a2398a8dd8444f6df3723898cb5fe2a from main
-rw-r--r--django/core/management/commands/dumpdata.py5
-rw-r--r--docs/releases/5.0.2.txt4
-rw-r--r--tests/fixtures/models.py6
-rw-r--r--tests/fixtures/tests.py16
4 files changed, 30 insertions, 1 deletions
diff --git a/django/core/management/commands/dumpdata.py b/django/core/management/commands/dumpdata.py
index cc183517e3..01ff8974dd 100644
--- a/django/core/management/commands/dumpdata.py
+++ b/django/core/management/commands/dumpdata.py
@@ -219,7 +219,10 @@ class Command(BaseCommand):
if count_only:
yield queryset.order_by().count()
else:
- yield from queryset.iterator()
+ chunk_size = (
+ 2000 if queryset._prefetch_related_lookups else None
+ )
+ yield from queryset.iterator(chunk_size=chunk_size)
try:
self.stdout.ending = None
diff --git a/docs/releases/5.0.2.txt b/docs/releases/5.0.2.txt
index 8e2d648ecc..83f1af7b4f 100644
--- a/docs/releases/5.0.2.txt
+++ b/docs/releases/5.0.2.txt
@@ -24,3 +24,7 @@ Bugfixes
``FilteredRelation()`` with querysets as right-hand sides (:ticket:`35135`).
``FilteredRelation()`` now raises a ``ValueError`` on querysets as right-hand
sides.
+
+* Fixed a regression in Django 5.0 that caused a crash of the ``dumpdata``
+ management command when a base queryset used ``prefetch_related()``
+ (:ticket:`35159`).
diff --git a/tests/fixtures/models.py b/tests/fixtures/models.py
index 37b0066d70..c87e170afc 100644
--- a/tests/fixtures/models.py
+++ b/tests/fixtures/models.py
@@ -101,9 +101,15 @@ class ProxySpy(Spy):
proxy = True
+class VisaManager(models.Manager):
+ def get_queryset(self):
+ return super().get_queryset().prefetch_related("permissions")
+
+
class Visa(models.Model):
person = models.ForeignKey(Person, models.CASCADE)
permissions = models.ManyToManyField(Permission, blank=True)
+ objects = VisaManager()
def __str__(self):
return "%s %s" % (
diff --git a/tests/fixtures/tests.py b/tests/fixtures/tests.py
index 78141b25b4..bce55bc355 100644
--- a/tests/fixtures/tests.py
+++ b/tests/fixtures/tests.py
@@ -830,6 +830,22 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
)
self.assertEqual(len(warning_list), 0)
+ def test_dumpdata_objects_with_prefetch_related(self):
+ management.call_command(
+ "loaddata", "fixture6.json", "fixture8.json", verbosity=0
+ )
+ with self.assertNumQueries(5):
+ self._dumpdata_assert(
+ ["fixtures.visa"],
+ '[{"fields": {"permissions": [["add_user", "auth", "user"]],'
+ '"person": ["Stephane Grappelli"]},'
+ '"model": "fixtures.visa", "pk": 2},'
+ '{"fields": {"permissions": [], "person": ["Prince"]},'
+ '"model": "fixtures.visa", "pk": 3}]',
+ natural_foreign_keys=True,
+ primary_keys="2,3",
+ )
+
def test_compress_format_loading(self):
# Load fixture 4 (compressed), using format specification
management.call_command("loaddata", "fixture4.json", verbosity=0)