From e50add6ca1605dcc06c8c5a5770342779a4d5124 Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Wed, 29 Nov 2017 01:06:45 -0500 Subject: [PATCH] Fixed #28856 -- Fixed a regression in caching of a GenericForeignKey pointing to a MTI model. Regression in b9f8635f58ad743995cad2081b3dc395e55761e5. --- django/db/models/fields/related.py | 3 +++ docs/releases/1.11.8.txt | 3 +++ tests/generic_relations_regress/tests.py | 6 ++++++ tests/model_fields/test_foreignkey.py | 10 ++++++++++ tests/serializers/test_xml.py | 6 ------ tests/serializers/tests.py | 6 +----- 6 files changed, 23 insertions(+), 11 deletions(-) diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 34123fd4de..e2e2bb23a6 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -872,6 +872,9 @@ class ForeignKey(ForeignObject): kwargs['to_field'] = self.remote_field.field_name return name, path, args, kwargs + def to_python(self, value): + return self.target_field.to_python(value) + @property def target_field(self): return self.foreign_related_fields[0] diff --git a/docs/releases/1.11.8.txt b/docs/releases/1.11.8.txt index 959731bbd5..596ea434ec 100644 --- a/docs/releases/1.11.8.txt +++ b/docs/releases/1.11.8.txt @@ -27,3 +27,6 @@ Bugfixes * Made query lookups for ``CICharField``, ``CIEmailField``, and ``CITextField`` use a ``citext`` cast (:ticket:`28702`). + +* Fixed a regression in caching of a ``GenericForeignKey`` when the referenced + model instance uses multi-table inheritance (:ticket:`28856`). diff --git a/tests/generic_relations_regress/tests.py b/tests/generic_relations_regress/tests.py index 9add025a46..cfac484053 100644 --- a/tests/generic_relations_regress/tests.py +++ b/tests/generic_relations_regress/tests.py @@ -48,6 +48,12 @@ class GenericRelationTests(TestCase): TextLink.objects.create(content_object=oddrel) oddrel.delete() + def test_coerce_object_id_remote_field_cache_persistence(self): + restaurant = Restaurant.objects.create() + CharLink.objects.create(content_object=restaurant) + charlink = CharLink.objects.latest('pk') + self.assertIs(charlink.content_object, charlink.content_object) + def test_q_object_or(self): """ SQL query parameters for generic relations are properly diff --git a/tests/model_fields/test_foreignkey.py b/tests/model_fields/test_foreignkey.py index 1617f7f310..7c99d8e34a 100644 --- a/tests/model_fields/test_foreignkey.py +++ b/tests/model_fields/test_foreignkey.py @@ -93,3 +93,13 @@ class ForeignKeyTests(TestCase): assert_app_model_resolved('model_fields') assert_app_model_resolved('tests') + + @isolate_apps('model_fields') + def test_to_python(self): + class Foo(models.Model): + pass + + class Bar(models.Model): + fk = models.ForeignKey(Foo, models.CASCADE) + + self.assertEqual(Bar._meta.get_field('fk').to_python('1'), 1) diff --git a/tests/serializers/test_xml.py b/tests/serializers/test_xml.py index ea9677d87f..b11cfdd864 100644 --- a/tests/serializers/test_xml.py +++ b/tests/serializers/test_xml.py @@ -29,12 +29,6 @@ class XmlSerializerTestCase(SerializersTestBase, TestCase): """ # NOQA - @staticmethod - def _comparison_value(value): - # The XML serializer handles everything as strings, so comparisons - # need to be performed on the stringified value - return str(value) - @staticmethod def _validate_output(serial_str): try: diff --git a/tests/serializers/tests.py b/tests/serializers/tests.py index 0ea60f0f64..66fc2ef40c 100644 --- a/tests/serializers/tests.py +++ b/tests/serializers/tests.py @@ -90,10 +90,6 @@ class SerializerRegistrationTests(SimpleTestCase): class SerializersTestBase: serializer_name = None # Set by subclasses to the serialization format name - @staticmethod - def _comparison_value(value): - return value - def setUp(self): sports = Category.objects.create(name="Sports") music = Category.objects.create(name="Music") @@ -193,7 +189,7 @@ class SerializersTestBase: self.assertFalse(self._get_field_values(serial_str, 'author')) for obj in serializers.deserialize(self.serializer_name, serial_str): - self.assertEqual(obj.object.pk, self._comparison_value(self.joe.pk)) + self.assertEqual(obj.object.pk, self.joe.pk) def test_serialize_field_subset(self): """Output can be restricted to a subset of fields"""