diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index 4caed4f..937e9d3 100644
a
|
b
|
class ReverseSingleRelatedObjectDescriptor(six.with_metaclass(RenameRelatedObjec
|
331 | 331 | if not router.allow_relation(value, instance): |
332 | 332 | raise ValueError('Cannot assign "%r": the current database router prevents this relation.' % value) |
333 | 333 | |
| 334 | pk = tuple(getattr(value, field.attname, None) for _, field in self.field.related_fields) |
| 335 | if None in pk and self.field.null is False: |
| 336 | raise ValueError('Cannot assign "%r": "%s" instance isn\'t saved in the database.' % |
| 337 | (value, self.field.rel.to._meta.object_name)) |
| 338 | |
334 | 339 | # If we're setting the value of a OneToOneField to None, we need to clear |
335 | 340 | # out the cache on any old related object. Otherwise, deleting the |
336 | 341 | # previously-related object will also cause this object to be deleted, |
… |
… |
class ReverseSingleRelatedObjectDescriptor(six.with_metaclass(RenameRelatedObjec
|
352 | 357 | |
353 | 358 | # Set the value of the related field |
354 | 359 | for lh_field, rh_field in self.field.related_fields: |
355 | | try: |
356 | | setattr(instance, lh_field.attname, getattr(value, rh_field.attname)) |
357 | | except AttributeError: |
358 | | setattr(instance, lh_field.attname, None) |
| 360 | setattr(instance, lh_field.attname, getattr(value, rh_field.attname, None)) |
359 | 361 | |
360 | 362 | # Since we already know what the related object is, seed the related |
361 | 363 | # object caches now, too. This avoids another db hit if you get the |
diff --git a/tests/model_regress/tests.py b/tests/model_regress/tests.py
index f84a40b..c1f1b97 100644
a
|
b
|
import sys
|
6 | 6 | import unittest |
7 | 7 | |
8 | 8 | from django.core.exceptions import ValidationError |
9 | | from django.test import TestCase, skipUnlessDBFeature |
10 | | from django.utils import six |
11 | | from django.utils import tzinfo |
12 | 9 | from django.db import connection, router |
13 | 10 | from django.db.models.sql import InsertQuery |
| 11 | from django.test import TestCase, skipUnlessDBFeature |
| 12 | from django.utils import six, tzinfo |
14 | 13 | |
15 | 14 | from .models import (Worker, Article, Party, Event, Department, |
16 | 15 | BrokenUnicodeMethod, NonAutoPK, Model1, Model2, Model3) |
… |
… |
class ModelTests(TestCase):
|
214 | 213 | m3 = Model3.objects.get(model2=1000) |
215 | 214 | m3.model2 |
216 | 215 | |
| 216 | def test_assign_unsaved_instance_to_fk(self): |
| 217 | """ |
| 218 | Regression for #10811: Can't assign an unsaved instance to a FK |
| 219 | """ |
| 220 | w = Worker(name="Joe") |
| 221 | d = Department(name="Accounting") # not saved in the database |
| 222 | with six.assertRaisesRegex(self, ValueError, |
| 223 | 'Cannot assign "<Department: Accounting>": ' |
| 224 | '"Department" instance isn\'t saved in the database.'): |
| 225 | w.department = d |
| 226 | |
217 | 227 | |
218 | 228 | class ModelValidationTest(TestCase): |
219 | 229 | def test_pk_validation(self): |