From f5a33e4840d3ad4d1199e99f5a17a9af1d2176f9 Mon Sep 17 00:00:00 2001 From: Raphael Merx Date: Wed, 16 Sep 2015 19:49:40 -0700 Subject: [PATCH] Fixed #25296 -- Prevented model related object cache pollution when create() fails due to an unsaved object. --- django/db/models/base.py | 3 +++ tests/one_to_one/tests.py | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/django/db/models/base.py b/django/db/models/base.py index 2c4a475cd4..be1cb48df9 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -643,6 +643,9 @@ class Model(six.with_metaclass(ModelBase)): # constraints aren't supported by the database, there's the # unavoidable risk of data corruption. if obj and obj.pk is None: + # Remove the object from a related instance cache. + if not field.remote_field.multiple: + delattr(obj, field.remote_field.get_cache_name()) raise ValueError( "save() prohibited to prevent data loss due to " "unsaved related object '%s'." % field.name diff --git a/tests/one_to_one/tests.py b/tests/one_to_one/tests.py index 1319cf0d9b..25d20dc2c9 100644 --- a/tests/one_to_one/tests.py +++ b/tests/one_to_one/tests.py @@ -135,9 +135,14 @@ class OneToOneTests(TestCase): should raise an exception. """ place = Place(name='User', address='London') + with self.assertRaises(Restaurant.DoesNotExist): + place.restaurant msg = "save() prohibited to prevent data loss due to unsaved related object 'place'." with self.assertRaisesMessage(ValueError, msg): Restaurant.objects.create(place=place, serves_hot_dogs=True, serves_pizza=False) + # place should not cache restaurant + with self.assertRaises(Restaurant.DoesNotExist): + place.restaurant def test_reverse_relationship_cache_cascade(self): """