From e41f9f94505f690525f16af8bd10e62e22bc0207 Mon Sep 17 00:00:00 2001 From: Oguzhan Akan <37854131+oguzhanakan0@users.noreply.github.com> Date: Fri, 8 Sep 2023 09:47:11 +0300 Subject: [PATCH] Fixed #34816 -- Fixed GenericForeignKey crash when checking cache for primary keys with different types. --- AUTHORS | 1 + django/contrib/contenttypes/fields.py | 4 ++-- tests/generic_relations_regress/tests.py | 12 ++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index 2c922b4ff3..51a2b1197a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -759,6 +759,7 @@ answer newbie questions, and generally made Django that much better: Octavio Peri oggie rob oggy + Oguzhan Akan Oliver Beattie Oliver Rutherfurd Olivier Le Thanh Duong diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py index 35fcd0d908..f92ecfa6c0 100644 --- a/django/contrib/contenttypes/fields.py +++ b/django/contrib/contenttypes/fields.py @@ -242,8 +242,8 @@ class GenericForeignKey(FieldCacheMixin): ct_match = ( ct_id == self.get_content_type(obj=rel_obj, using=instance._state.db).id ) - pk_match = rel_obj._meta.pk.to_python(pk_val) == rel_obj.pk - if ct_match and pk_match: + pk_match = ct_match and rel_obj._meta.pk.to_python(pk_val) == rel_obj.pk + if pk_match: return rel_obj else: rel_obj = None diff --git a/tests/generic_relations_regress/tests.py b/tests/generic_relations_regress/tests.py index b7ecb499eb..a3d54be1da 100644 --- a/tests/generic_relations_regress/tests.py +++ b/tests/generic_relations_regress/tests.py @@ -1,3 +1,4 @@ +from django.contrib.contenttypes.models import ContentType from django.db.models import ProtectedError, Q, Sum from django.forms.models import modelform_factory from django.test import TestCase, skipIfDBFeature @@ -332,3 +333,14 @@ class GenericRelationTests(TestCase): self.assertSequenceEqual(qs, [link2]) qs = Link.objects.exclude(places__name="Test Place 1") self.assertSequenceEqual(qs, [link2]) + + def test_check_cached_value_pk_different_type(self): + """Primary key is not checked if the content type doesn't match.""" + board = Board.objects.create(name="some test") + oddrel = OddRelation1.objects.create(name="clink") + charlink = CharLink.objects.create(content_object=oddrel) + charlink = CharLink.objects.get(pk=charlink.pk) + self.assertEqual(charlink.content_object, oddrel) + charlink.object_id = board.pk + charlink.content_type_id = ContentType.objects.get_for_model(Board).id + self.assertEqual(charlink.content_object, board)