Forráskód Böngészése

[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
Mariusz Felisiak 1 éve
szülő
commit
7453d6a807

+ 4 - 1
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

+ 4 - 0
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`).

+ 6 - 0
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" % (

+ 16 - 0
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)