mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #24873 -- Prevented nested Prefetch objects from being overwritten.
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
| @@ -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): | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user