diff options
Diffstat (limited to 'django')
| -rw-r--r-- | django/db/models/fields/related.py | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 57392fd62f..529898ea27 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -112,9 +112,9 @@ class RelatedField(object): def do_related_class(self, other, cls): self.set_attributes_from_rel() - related = RelatedObject(other, cls, self) + self.related = RelatedObject(other, cls, self) if not cls._meta.abstract: - self.contribute_to_related_class(other, related) + self.contribute_to_related_class(other, self.related) def get_db_prep_lookup(self, lookup_type, value): # If we are doing a lookup on a Related Field, we must be @@ -184,7 +184,6 @@ class SingleRelatedObjectDescriptor(object): def __get__(self, instance, instance_type=None): if instance is None: return self - try: return getattr(instance, self.cache_name) except AttributeError: @@ -232,6 +231,7 @@ class ReverseSingleRelatedObjectDescriptor(object): def __get__(self, instance, instance_type=None): if instance is None: return self + cache_name = self.field.get_cache_name() try: return getattr(instance, cache_name) @@ -272,6 +272,29 @@ class ReverseSingleRelatedObjectDescriptor(object): (value, instance._meta.object_name, self.field.name, self.field.rel.to._meta.object_name)) + # If we're setting the value of a OneToOneField to None, we need to clear + # out the cache on any old related object. Otherwise, deleting the + # previously-related object will also cause this object to be deleted, + # which is wrong. + if value is None: + # Look up the previously-related object, which may still be available + # since we've not yet cleared out the related field. + # Use the cache directly, instead of the accessor; if we haven't + # populated the cache, then we don't care - we're only accessing + # the object to invalidate the accessor cache, so there's no + # need to populate the cache just to expire it again. + related = getattr(instance, self.field.get_cache_name(), None) + + # If we've got an old related object, we need to clear out its + # cache. This cache also might not exist if the related object + # hasn't been accessed yet. + if related: + cache_name = '_%s_cache' % self.field.related.get_accessor_name() + try: + delattr(related, cache_name) + except AttributeError: + pass + # Set the value of the related field try: val = getattr(value, self.field.rel.get_related_field().attname) |
