diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index 419695b..f5d4fa3 100644
a
|
b
|
class RelatedField(object):
|
112 | 112 | |
113 | 113 | def do_related_class(self, other, cls): |
114 | 114 | self.set_attributes_from_rel() |
115 | | related = RelatedObject(other, cls, self) |
| 115 | self.related = RelatedObject(other, cls, self) |
116 | 116 | if not cls._meta.abstract: |
117 | | self.contribute_to_related_class(other, related) |
| 117 | self.contribute_to_related_class(other, self.related) |
118 | 118 | |
119 | 119 | def get_db_prep_lookup(self, lookup_type, value): |
120 | 120 | # If we are doing a lookup on a Related Field, we must be |
… |
… |
class ReverseSingleRelatedObjectDescriptor(object):
|
271 | 271 | (value, instance._meta.object_name, |
272 | 272 | self.field.name, self.field.rel.to._meta.object_name)) |
273 | 273 | |
| 274 | # If we're setting the value of a OneToOneField to None, we need to clear |
| 275 | # out the cache on any old related object. Otherwise, deleting the |
| 276 | # previously-related object will also cause this object to be deleted, |
| 277 | # which is wrong. |
| 278 | if value is None: |
| 279 | # Look up the previously-related object, which is still available |
| 280 | # since we've not year cleared out the related field. This could |
| 281 | # raise a DoesNotExist exception, which we need to ignore. |
| 282 | try: |
| 283 | related = getattr(instance, self.field.name, None) |
| 284 | except self.field.rel.to.DoesNotExist: |
| 285 | related = None |
| 286 | |
| 287 | # If we've got an old related object, we need to clear out its |
| 288 | # cache. This cache also might not exist if the related object |
| 289 | # hasn't been accessed yet. |
| 290 | if related: |
| 291 | cache_name = '_%s_cache' % self.field.related.get_accessor_name() |
| 292 | try: |
| 293 | delattr(related, cache_name) |
| 294 | except AttributeError: |
| 295 | pass |
| 296 | |
274 | 297 | # Set the value of the related field |
275 | 298 | try: |
276 | 299 | val = getattr(value, self.field.rel.get_related_field().attname) |
diff --git a/tests/regressiontests/one_to_one_regress/tests.py b/tests/regressiontests/one_to_one_regress/tests.py
new file mode 100644
index 0000000..b9b171b
-
|
+
|
|
| 1 | from django.test import TestCase |
| 2 | from regressiontests.one_to_one_regress.models import Place, UndergroundBar |
| 3 | |
| 4 | class OneToOneDeletionTests(TestCase): |
| 5 | def test_reverse_relationship_cache_cascade(self): |
| 6 | """ |
| 7 | Regression test for #9023: accessing the reverse relationship shouldn't |
| 8 | result in a cascading delete(). |
| 9 | """ |
| 10 | place = Place.objects.create(name="Dempsey's", address="623 Vermont St") |
| 11 | bar = UndergroundBar.objects.create(place=place, serves_cocktails=False) |
| 12 | |
| 13 | # The bug in #9023: if you access the one-to-one relation *before* |
| 14 | # setting to None and deleting, the cascade happens anyway. |
| 15 | place.undergroundbar |
| 16 | bar.place = None |
| 17 | bar.save() |
| 18 | place.delete() |
| 19 | |
| 20 | self.assertEqual(Place.objects.all().count(), 0) |
| 21 | self.assertEqual(UndergroundBar.objects.all().count(), 1) |
| 22 | |
| 23 | No newline at end of file |