Ticket #14368: 14368.patch

File 14368.patch, 3.4 KB (added by gruszczy, 5 years ago)
  • django/db/models/fields/related.py

     
    254254                    raise ValueError('Cannot assign "%r": instance is on database "%s", value is on database "%s"' %
    255255                                        (value, instance._state.db, value._state.db))
    256256
    257         # Set the value of the related field to the value of the related object's related field
    258         setattr(value, self.related.field.attname, getattr(instance, self.related.field.rel.get_related_field().attname))
     257        if value is not None:
     258            # Set the value of the related field to the value of the related object's related field
     259            setattr(value, self.related.field.attname, getattr(instance, self.related.field.rel.get_related_field().attname))
     260   
     261            # Since we already know what the related object is, seed the related
     262            # object caches now, too. This avoids another db hit if you get the
     263            # object you just set.
     264            setattr(instance, self.cache_name, value)
     265            setattr(value, self.related.field.get_cache_name(), instance)
     266        else:
     267            value = getattr(instance, self.related.var_name, None)
     268            if value is not None:
     269                setattr(value, self.related.field.name, None)
     270            try:
     271                delattr(instance, self.cache_name)
     272            except AttributeError:
     273                pass
    259274
    260         # Since we already know what the related object is, seed the related
    261         # object caches now, too. This avoids another db hit if you get the
    262         # object you just set.
    263         setattr(instance, self.cache_name, value)
    264         setattr(value, self.related.field.get_cache_name(), instance)
    265 
    266275class ReverseSingleRelatedObjectDescriptor(object):
    267276    # This class provides the functionality that makes the related-object
    268277    # managers available as attributes on a model class, for fields that have
  • tests/modeltests/one_to_one/tests.py

     
     1from django.test import TestCase
     2
     3from models import First, Second
     4
     5class OneToOneTestCase(TestCase):
     6   
     7    def test_set_related_to_none(self):
     8        # regression test for #14368
     9        first = First.objects.create()
     10        second = Second.objects.create()
     11        first.second = second
     12        first.second = None
     13        self.assertRaises(Second.DoesNotExist, getattr, first, 'second')
     14        self.assert_(second.first is None)
  • tests/modeltests/one_to_one/models.py

     
    4646    def __unicode__(self):
    4747        return u"Multimodel %s" % self.name
    4848
     49class First(models.Model):
     50    pass
     51
     52class Second(models.Model):
     53  first = models.OneToOneField(First, null=True)
     54
    4955__test__ = {'API_TESTS':"""
    5056# Create a couple of Places.
    5157>>> p1 = Place(name='Demon Dogs', address='944 W. Fullerton')
     
    190196...         print "Fail with %s" % type(e)
    191197Pass
    192198>>> transaction.savepoint_rollback(sid)
    193 
    194199"""}
Back to Top