Commit 74261bc5 authored by Gagaro's avatar Gagaro Committed by Tim Graham
Browse files

Fixed #24873 -- Prevented nested Prefetch objects from being overwritten.

parent 06747ee7
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -1538,7 +1538,12 @@ def prefetch_one_level(instances, prefetcher, lookup, level):
    # contains some prefetch_related lookups. We don't want to trigger the
    # prefetch_related functionality by evaluating the query. Rather, we need
    # to merge in the prefetch_related lookups.
    additional_lookups = getattr(rel_qs, '_prefetch_related_lookups', [])
    # Copy the lookups in case it is a Prefetch object which could be reused
    # later (happens in nested prefetch_related).
    additional_lookups = [
        copy.copy(additional_lookup) for additional_lookup
        in getattr(rel_qs, '_prefetch_related_lookups', [])
    ]
    if additional_lookups:
        # Don't need to clone because the manager should have given us a fresh
        # instance, so we access an internal instead of using public interface
+11 −0
Original line number Diff line number Diff line
@@ -626,6 +626,17 @@ class CustomPrefetchTests(TestCase):
        room = Room.objects.filter(main_room_of__isnull=False).prefetch_related(Prefetch('main_room_of', queryset=houses.filter(address='DoesNotExist'), to_attr='main_room_of_attr')).first()
        self.assertIsNone(room.main_room_of_attr)

    def test_nested_prefetch_related_are_not_overwritten(self):
        # Regression test for #24873
        houses_2 = House.objects.prefetch_related(Prefetch('rooms'))
        persons = Person.objects.prefetch_related(Prefetch('houses', queryset=houses_2))
        houses = House.objects.prefetch_related(Prefetch('occupants', queryset=persons))
        list(houses)  # queryset must be evaluated once to reproduce the bug.
        self.assertEqual(
            houses.all()[0].occupants.all()[0].houses.all()[1].rooms.all()[0],
            self.room2_1
        )


class DefaultManagerTests(TestCase):