From 1abd177696ef72843557980fbdd352176ed2800e Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Sat, 19 Sep 2015 13:36:38 +0200 Subject: [PATCH] [1.8.x] Fixed #25160 (again) -- Moved data loss check on reverse relations. Moved data loss check when assigning to a reverse one-to-one relation on an unsaved instance to Model.save(). This is exactly the same change as e4b813c but for reverse relations. Backport of c3904de from master --- django/db/models/fields/related.py | 6 ------ docs/releases/1.8.5.txt | 4 ++++ docs/releases/1.8.txt | 3 +++ tests/one_to_one/tests.py | 12 +++++++----- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 91bc7f00ba..dec9e555f3 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -506,12 +506,6 @@ class SingleRelatedObjectDescriptor(object): raise ValueError('Cannot assign "%r": the current database router prevents this relation.' % value) related_pk = tuple(getattr(instance, field.attname) for field in self.related.field.foreign_related_fields) - if None in related_pk: - raise ValueError( - 'Cannot assign "%r": "%s" instance isn\'t saved in the database.' % - (value, instance._meta.object_name) - ) - # Set the value of the related field to the value of the related object's related field for index, field in enumerate(self.related.field.local_related_fields): setattr(value, field.attname, related_pk[index]) diff --git a/docs/releases/1.8.5.txt b/docs/releases/1.8.5.txt index 5a19a50137..ce03577cde 100644 --- a/docs/releases/1.8.5.txt +++ b/docs/releases/1.8.5.txt @@ -39,3 +39,7 @@ Bugfixes * Fixed custom queryset chaining with ``values()`` and ``values_list()`` (:ticket:`20625`). + +* Moved the :ref:`unsaved model instance assignment data loss check + ` on reverse relations to ``Model.save()`` + (:ticket:`25160`). diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index 3200e81f46..ec35dbe7a2 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -701,6 +701,9 @@ Assigning unsaved objects to relations raises an error ... ValueError: save() prohibited to prevent data loss due to unsaved related object 'author'. + A similar check on assignment to reverse one-to-one relations was removed + in Django 1.8.5. + Assigning unsaved objects to a :class:`~django.db.models.ForeignKey`, :class:`~django.contrib.contenttypes.fields.GenericForeignKey`, and :class:`~django.db.models.OneToOneField` now raises a :exc:`ValueError`. diff --git a/tests/one_to_one/tests.py b/tests/one_to_one/tests.py index b71ee0645a..727ff11efd 100644 --- a/tests/one_to_one/tests.py +++ b/tests/one_to_one/tests.py @@ -371,13 +371,15 @@ class OneToOneTests(TestCase): """ p = Place() b = UndergroundBar.objects.create() - msg = ( - 'Cannot assign "": "Place" ' - 'instance isn\'t saved in the database.' - ) + + # Assigning a reverse relation on an unsaved object is allowed. + p.undergroundbar = b + + # However saving the object is not allowed. + msg = "save() prohibited to prevent data loss due to unsaved related object 'place'." with self.assertNumQueries(0): with self.assertRaisesMessage(ValueError, msg): - p.undergroundbar = b + b.save() def test_nullable_o2o_delete(self): u = UndergroundBar.objects.create(place=self.p1)