Browse Source

Fixed #34816 -- Fixed GenericForeignKey crash when checking cache for primary keys with different types.

Oguzhan Akan 1 year ago
parent
commit
e41f9f9450
3 changed files with 15 additions and 2 deletions
  1. 1 0
      AUTHORS
  2. 2 2
      django/contrib/contenttypes/fields.py
  3. 12 0
      tests/generic_relations_regress/tests.py

+ 1 - 0
AUTHORS

@@ -759,6 +759,7 @@ answer newbie questions, and generally made Django that much better:
     Octavio Peri <octaperi@gmail.com>
     oggie rob <oz.robharvey@gmail.com>
     oggy <ognjen.maric@gmail.com>
+    Oguzhan Akan <oakan118@gmail.com>
     Oliver Beattie <oliver@obeattie.com>
     Oliver Rutherfurd <http://rutherfurd.net/>
     Olivier Le Thanh Duong <olivier@lethanh.be>

+ 2 - 2
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

+ 12 - 0
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)