Ticket #10811: 10811.patch

File 10811.patch, 3.0 KB (added by aaugustin, 18 months ago)
  • django/db/models/fields/related.py

    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 
    331331                if not router.allow_relation(value, instance):
    332332                    raise ValueError('Cannot assign "%r": the current database router prevents this relation.' % value)
    333333
     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
    334339        # If we're setting the value of a OneToOneField to None, we need to clear
    335340        # out the cache on any old related object. Otherwise, deleting the
    336341        # previously-related object will also cause this object to be deleted,
    class ReverseSingleRelatedObjectDescriptor(six.with_metaclass(RenameRelatedObjec 
    352357
    353358        # Set the value of the related field
    354359        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))
    359361
    360362        # Since we already know what the related object is, seed the related
    361363        # object caches now, too. This avoids another db hit if you get the
  • tests/model_regress/tests.py

    diff --git a/tests/model_regress/tests.py b/tests/model_regress/tests.py
    index f84a40b..c1f1b97 100644
    a b import sys 
    66import unittest
    77
    88from django.core.exceptions import ValidationError
    9 from django.test import TestCase, skipUnlessDBFeature
    10 from django.utils import six
    11 from django.utils import tzinfo
    129from django.db import connection, router
    1310from django.db.models.sql import InsertQuery
     11from django.test import TestCase, skipUnlessDBFeature
     12from django.utils import six, tzinfo
    1413
    1514from .models import (Worker, Article, Party, Event, Department,
    1615    BrokenUnicodeMethod, NonAutoPK, Model1, Model2, Model3)
    class ModelTests(TestCase): 
    214213        m3 = Model3.objects.get(model2=1000)
    215214        m3.model2
    216215
     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
    217227
    218228class ModelValidationTest(TestCase):
    219229    def test_pk_validation(self):
Back to Top