mirror of
https://github.com/django/django.git
synced 2025-06-05 03:29:12 +00:00
Fixed #34819 -- Made GenericForeignKey prefetching use matching pk representations.
Ensured that rel_obj_attr and instance_attr return matching (pk, cls) tuples in GenericForeignKey.get_prefetch_queryset(), preventing mismatches when prefetching related objects where pk and get_prep_value() differ. Using value_to_string() also makes this code compatible with composite primary keys.
This commit is contained in:
parent
7d9aab8da0
commit
d5c19f9b32
@ -205,14 +205,11 @@ class GenericForeignKey(FieldCacheMixin, Field):
|
|||||||
model = self.get_content_type(
|
model = self.get_content_type(
|
||||||
id=ct_id, using=obj._state.db
|
id=ct_id, using=obj._state.db
|
||||||
).model_class()
|
).model_class()
|
||||||
return (
|
return str(getattr(obj, self.fk_field)), model
|
||||||
model._meta.pk.get_prep_value(getattr(obj, self.fk_field)),
|
|
||||||
model,
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
ret_val,
|
ret_val,
|
||||||
lambda obj: (obj.pk, obj.__class__),
|
lambda obj: (obj._meta.pk.value_to_string(obj), obj.__class__),
|
||||||
gfk_key,
|
gfk_key,
|
||||||
True,
|
True,
|
||||||
self.name,
|
self.name,
|
||||||
|
@ -216,6 +216,15 @@ class Comment(models.Model):
|
|||||||
ordering = ["id"]
|
ordering = ["id"]
|
||||||
|
|
||||||
|
|
||||||
|
class ArticleCustomUUID(models.Model):
|
||||||
|
class CustomUUIDField(models.UUIDField):
|
||||||
|
def get_prep_value(self, value):
|
||||||
|
return str(value)
|
||||||
|
|
||||||
|
id = CustomUUIDField(primary_key=True, default=uuid.uuid4)
|
||||||
|
name = models.CharField(max_length=30)
|
||||||
|
|
||||||
|
|
||||||
# Models for lookup ordering tests
|
# Models for lookup ordering tests
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ from django.test.utils import CaptureQueriesContext
|
|||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
Article,
|
Article,
|
||||||
|
ArticleCustomUUID,
|
||||||
Author,
|
Author,
|
||||||
Author2,
|
Author2,
|
||||||
AuthorAddress,
|
AuthorAddress,
|
||||||
@ -1179,6 +1180,14 @@ class GenericRelationTests(TestCase):
|
|||||||
qs = Comment.objects.prefetch_related("content_object_uuid")
|
qs = Comment.objects.prefetch_related("content_object_uuid")
|
||||||
self.assertEqual([c.content_object_uuid for c in qs], [article])
|
self.assertEqual([c.content_object_uuid for c in qs], [article])
|
||||||
|
|
||||||
|
def test_prefetch_GFK_uses_prepped_primary_key(self):
|
||||||
|
article = ArticleCustomUUID.objects.create(name="Blanche")
|
||||||
|
Comment.objects.create(comment="Enchantment", content_object_uuid=article)
|
||||||
|
obj = Comment.objects.prefetch_related("content_object_uuid").get(
|
||||||
|
comment="Enchantment"
|
||||||
|
)
|
||||||
|
self.assertEqual(obj.content_object_uuid, article)
|
||||||
|
|
||||||
def test_prefetch_GFK_fk_pk(self):
|
def test_prefetch_GFK_fk_pk(self):
|
||||||
book = Book.objects.create(title="Poems")
|
book = Book.objects.create(title="Poems")
|
||||||
book_with_year = BookWithYear.objects.create(book=book, published_year=2019)
|
book_with_year = BookWithYear.objects.create(book=book, published_year=2019)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user