Fixed problem with refs #10811.

When 'to_field' is specified with a FK, then we need to check the pk value
the object.
This commit is contained in:
Anubhav Joshi 2014-06-30 18:43:35 +05:30 committed by Tim Graham
parent add78c58b5
commit fd5897193f
3 changed files with 16 additions and 7 deletions

View File

@ -623,13 +623,13 @@ class ReverseSingleRelatedObjectDescriptor(object):
# Set the values of the related field. # Set the values of the related field.
else: else:
for lh_field, rh_field in self.field.related_fields: for lh_field, rh_field in self.field.related_fields:
val = getattr(value, rh_field.attname) pk = value._get_pk_val()
if val is None: if pk is None:
raise ValueError( raise ValueError(
'Cannot assign "%r": "%s" instance isn\'t saved in the database.' % 'Cannot assign "%r": "%s" instance isn\'t saved in the database.' %
(value, self.field.rel.to._meta.object_name) (value, self.field.rel.to._meta.object_name)
) )
setattr(instance, lh_field.attname, val) setattr(instance, lh_field.attname, getattr(value, rh_field.attname))
# Since we already know what the related object is, seed the related # Since we already know what the related object is, seed the related
# object caches now, too. This avoids another db hit if you get the # object caches now, too. This avoids another db hit if you get the

View File

@ -26,7 +26,7 @@ class Third(models.Model):
class Parent(models.Model): class Parent(models.Model):
name = models.CharField(max_length=20) name = models.CharField(max_length=20, unique=True)
bestchild = models.ForeignKey('Child', null=True, related_name='favored_by') bestchild = models.ForeignKey('Child', null=True, related_name='favored_by')
@ -35,6 +35,10 @@ class Child(models.Model):
parent = models.ForeignKey(Parent) parent = models.ForeignKey(Parent)
class ToFieldChild(models.Model):
parent = models.ForeignKey(Parent, to_field='name')
# Multiple paths to the same model (#7110, #7125) # Multiple paths to the same model (#7110, #7125)
@python_2_unicode_compatible @python_2_unicode_compatible
class Category(models.Model): class Category(models.Model):

View File

@ -4,7 +4,7 @@ from django.db import models
from django.test import TestCase from django.test import TestCase
from .models import ( from .models import (
First, Third, Parent, Child, Category, Record, Relation, Car, Driver) First, Third, Parent, Child, ToFieldChild, Category, Record, Relation, Car, Driver)
class ManyToOneRegressionTests(TestCase): class ManyToOneRegressionTests(TestCase):
@ -71,6 +71,11 @@ class ManyToOneRegressionTests(TestCase):
% (p, Child.parent.field.rel.to._meta.object_name)): % (p, Child.parent.field.rel.to._meta.object_name)):
Child(parent=p) Child(parent=p)
with self.assertRaisesMessage(ValueError,
'Cannot assign "%r": "%s" instance isn\'t saved in the database.'
% (p, Child.parent.field.rel.to._meta.object_name)):
ToFieldChild(parent=p)
# Creation using attname keyword argument and an id will cause the # Creation using attname keyword argument and an id will cause the
# related object to be fetched. # related object to be fetched.
p = Parent.objects.get(name="Parent") p = Parent.objects.get(name="Parent")