summaryrefslogtreecommitdiff
path: root/tests/prefetch_related/tests.py
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2025-01-25 00:12:17 -0500
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-02-03 10:40:52 +0100
commit303c2569dad4e3222e94fc5b76dc7b83b35fde17 (patch)
tree0ca5414d69e009fd5e7eb8d6966e5ac0c4ce3746 /tests/prefetch_related/tests.py
parentaffad13d0c56184e2089cd7e8ecd80dd4217f6c4 (diff)
[5.2.x] Fixed #36135 -- Fixed reverse GenericRelation prefetching.
The get_(local|foreign)_related_value methods of GenericRelation must be reversed because it defines (from|to)_fields and associated related_fields in the reversed order as it's effectively a reverse GenericForeignKey itself. The related value methods must also account for the fact that referenced primary key values might be stored as a string on the model defining the GenericForeignKey but as integer on the model defining the GenericRelation. This is achieved by calling the to_python method of the involved content type in get_foreign_related_value just like GenericRelatedObjectManager does. Lastly reverse many-to-one manager's prefetch_related_querysets should use set_cached_value instead of direct attribute assignment as direct assignment might are disallowed on ReverseManyToOneDescriptor descriptors. This is likely something that was missed in f5233dc (refs #32511) when the is_cached guard was added. Thanks 1xinghuan for the report. Backport of 198b30168d4e94af42e0dc7967bd3259b5c5790b from main.
Diffstat (limited to 'tests/prefetch_related/tests.py')
-rw-r--r--tests/prefetch_related/tests.py14
1 files changed, 14 insertions, 0 deletions
diff --git a/tests/prefetch_related/tests.py b/tests/prefetch_related/tests.py
index 856f766d30..99e3cd6b80 100644
--- a/tests/prefetch_related/tests.py
+++ b/tests/prefetch_related/tests.py
@@ -1257,6 +1257,20 @@ class GenericRelationTests(TestCase):
],
)
+ def test_reverse_generic_relation(self):
+ # Create two distinct bookmarks to ensure the bookmark and
+ # tagged item models primary are offset.
+ first_bookmark = Bookmark.objects.create()
+ second_bookmark = Bookmark.objects.create()
+ TaggedItem.objects.create(
+ content_object=first_bookmark, favorite=second_bookmark
+ )
+ with self.assertNumQueries(2):
+ obj = TaggedItem.objects.prefetch_related("favorite_bookmarks").get()
+ with self.assertNumQueries(0):
+ prefetched_bookmarks = obj.favorite_bookmarks.all()
+ self.assertQuerySetEqual(prefetched_bookmarks, [second_bookmark])
+
class MultiTableInheritanceTest(TestCase):
@classmethod