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 |