summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2018-10-28 22:54:02 -0400
committerGitHub <noreply@github.com>2018-10-28 22:54:02 -0400
commitf77fc56c9671a2e2498e3920d79e247e6de18c16 (patch)
treec9f0a600a86e8d81bcf09ab6422ec841117877c7
parent5e8a07d69dee354d9e6dbda874f9454f4bc3491e (diff)
Fixed #29896 -- Fixed incorrect Model.save() cache relation clearing for foreign keys that use to_field.
Regression in ee49306176a2d2f1751cb890bd607d42c7c09196.
-rw-r--r--django/db/models/base.py6
-rw-r--r--docs/releases/2.1.3.txt3
-rw-r--r--tests/many_to_one/tests.py6
3 files changed, 12 insertions, 3 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 751f42bb9b..89faf9d1e1 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -676,9 +676,9 @@ class Model(metaclass=ModelBase):
"save() prohibited to prevent data loss due to "
"unsaved related object '%s'." % field.name
)
- # If the relationship's pk was changed, clear the cached
- # relationship.
- if obj and obj.pk != getattr(self, field.attname):
+ # If the relationship's pk/to_field was changed, clear the
+ # cached relationship.
+ if obj and getattr(obj, field.target_field.attname) != getattr(self, field.attname):
field.delete_cached_value(self)
using = using or router.db_for_write(self.__class__, instance=self)
diff --git a/docs/releases/2.1.3.txt b/docs/releases/2.1.3.txt
index bebd696d05..72ec3e4a32 100644
--- a/docs/releases/2.1.3.txt
+++ b/docs/releases/2.1.3.txt
@@ -17,3 +17,6 @@ Bugfixes
* Fixed a regression in Django 2.0 where test databases aren't reused with
``manage.py test --keepdb`` on MySQL (:ticket:`29827`).
+
+* Fixed a regression where cached foreign keys that use ``to_field`` were
+ incorrectly cleared in ``Model.save()`` (:ticket:`29896`).
diff --git a/tests/many_to_one/tests.py b/tests/many_to_one/tests.py
index a2ff587ab3..b04e6ad77a 100644
--- a/tests/many_to_one/tests.py
+++ b/tests/many_to_one/tests.py
@@ -666,3 +666,9 @@ class ManyToOneTests(TestCase):
self.a.reporter_id = self.r2.pk
self.a.save()
self.assertEqual(self.a.reporter, self.r2)
+
+ def test_cached_foreign_key_with_to_field_not_cleared_by_save(self):
+ parent = Parent.objects.create(name='a')
+ child = ToFieldChild.objects.create(parent=parent)
+ with self.assertNumQueries(0):
+ self.assertIs(child.parent, parent)