diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 6edf4198c4..e2dfca482a 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -97,8 +97,11 @@ class SingleRelatedObjectDescriptor(object): if instance is None: raise AttributeError, "%s must be accessed via instance" % self.related.opts.object_name # Set the value of the related field - setattr(value, self.related.field.attname, instance) - + setattr(value, self.related.field.rel.get_related_field().attname, instance) + + # Set the cache on the provided object to point to the new object + setattr(value, self.related.field.get_cache_name(), instance) + class ReverseSingleRelatedObjectDescriptor(object): # This class provides the functionality that makes the related-object # managers available as attributes on a model class, for fields that have @@ -142,7 +145,7 @@ class ReverseSingleRelatedObjectDescriptor(object): # Set the cache to point to the new object setattr(instance, self.field.get_cache_name(), value) - + class ForeignRelatedObjectsDescriptor(object): # This class provides the functionality that makes the related-object # managers available as attributes on a model class, for fields that have diff --git a/tests/modeltests/one_to_one/models.py b/tests/modeltests/one_to_one/models.py index 981edf0876..ef8a166afb 100644 --- a/tests/modeltests/one_to_one/models.py +++ b/tests/modeltests/one_to_one/models.py @@ -55,9 +55,33 @@ Traceback (most recent call last): ... DoesNotExist: Restaurant does not exist for {'place__pk': ...} +# Set the place using assignment notation. Because place is the primary key on Restaurant, +# the save will create a new restaurant +>>> r.place = p2 +>>> r.save() +>>> p2.restaurant +Ace Hardware the restaurant +>>> r.place +Ace Hardware the place + +# Set the place back again, using assignment in the reverse direction +# Need to reget restaurant object first, because the reverse set +# can't update the existing restaurant instance +>>> p1.restaurant = r +>>> r.save() +>>> p1.restaurant +Demon Dogs the restaurant + +>>> r = Restaurant.objects.get(pk=1) +>>> r.place +Demon Dogs the place + # Restaurant.objects.all() just returns the Restaurants, not the Places. +# Note that there are two restaurants - Ace Hardware the Restaurant was created +# in the call to r.place = p2. This means there are multiple restaurants referencing +# a single place... >>> Restaurant.objects.all() -[Demon Dogs the restaurant] +[Demon Dogs the restaurant, Ace Hardware the restaurant] # Place.objects.all() returns all Places, regardless of whether they have # Restaurants.