[2.0.x] Fixed #28742 -- Fixed AttributeError crash when assigning None to cached reverse relations.

Backport of fcfcf8aae4 from master
This commit is contained in:
Paulo 2017-10-29 12:01:04 +01:00 committed by Tim Graham
parent 1f4e9935ef
commit f2d5417d3b
2 changed files with 13 additions and 7 deletions

View File

@ -410,13 +410,10 @@ class ReverseOneToOneDescriptor:
if value is None: if value is None:
# Update the cached related instance (if any) & clear the cache. # Update the cached related instance (if any) & clear the cache.
try:
# Following the example above, this would be the cached # Following the example above, this would be the cached
# ``restaurant`` instance (if any). # ``restaurant`` instance (if any).
rel_obj = self.related.get_cached_value(instance) rel_obj = self.related.get_cached_value(instance, default=None)
except KeyError: if rel_obj is not None:
pass
else:
# Remove the ``restaurant`` instance from the ``place`` # Remove the ``restaurant`` instance from the ``place``
# instance cache. # instance cache.
self.related.delete_cached_value(instance) self.related.delete_cached_value(instance)

View File

@ -196,6 +196,15 @@ class OneToOneTests(TestCase):
# UndergroundBar. # UndergroundBar.
p.undergroundbar = None p.undergroundbar = None
def test_assign_none_to_null_cached_reverse_relation(self):
p = Place.objects.get(name='Demon Dogs')
# Prime the relation's cache with a value of None.
with self.assertRaises(Place.undergroundbar.RelatedObjectDoesNotExist):
getattr(p, 'undergroundbar')
# Assigning None works if there isn't a related UndergroundBar and the
# reverse cache has a value of None.
p.undergroundbar = None
def test_related_object_cache(self): def test_related_object_cache(self):
""" Regression test for #6886 (the related-object cache) """ """ Regression test for #6886 (the related-object cache) """