mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +00:00
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.
This commit is contained in:
committed by
Sarah Boyce
parent
d15454a6e8
commit
198b30168d
@@ -1254,6 +1254,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
|
||||
|
||||
Reference in New Issue
Block a user