[1.10.x] Fixed #27407 -- Made Model.delete(keep_parents=True) preserve parent reverse relationships.

Thanks Tim for the review.

Backport of 31a56e30cf from master
This commit is contained in:
Simon Charette 2016-09-10 20:30:14 -04:00
parent d2fc204694
commit b495d8e334
3 changed files with 16 additions and 0 deletions

View File

@ -210,7 +210,11 @@ class Collector(object):
collect_related=False,
reverse_dependency=True)
if collect_related:
parents = model._meta.parents
for related in get_candidate_relations_to_delete(model._meta):
# Preserve parent reverse relationships if keep_parents=True.
if keep_parents and related.model in parents:
continue
field = related.field
if field.remote_field.on_delete == DO_NOTHING:
continue

View File

@ -16,3 +16,6 @@ Bugfixes
* Fixed incorrect ``app_label`` / ``model_name`` arguments for
``allow_migrate()`` in ``makemigrations`` migration consistency checks
(:ticket:`27461`).
* Made ``Model.delete(keep_parents=True)`` preserve parent reverse
relationships in multi-table inheritance (:ticket:`27407`).

View File

@ -359,6 +359,15 @@ class DeletionTests(TestCase):
self.assertFalse(RChild.objects.filter(id=child.id).exists())
self.assertTrue(R.objects.filter(id=parent_id).exists())
def test_delete_with_keeping_parents_relationships(self):
child = RChild.objects.create()
parent_id = child.r_ptr_id
parent_referent_id = S.objects.create(r=child.r_ptr).pk
child.delete(keep_parents=True)
self.assertFalse(RChild.objects.filter(id=child.id).exists())
self.assertTrue(R.objects.filter(id=parent_id).exists())
self.assertTrue(S.objects.filter(pk=parent_referent_id).exists())
def test_queryset_delete_returns_num_rows(self):
"""
QuerySet.delete() should return the number of deleted rows and a