mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Fixed #30339 -- Made Model.delete(keep_parents=True) preserves nested parent reverse relationships.
Thanks Simon Charette for the review.
This commit is contained in:
parent
29601bca9b
commit
86a3ad351e
@ -212,7 +212,8 @@ class Collector:
|
|||||||
collect_related=False,
|
collect_related=False,
|
||||||
reverse_dependency=True)
|
reverse_dependency=True)
|
||||||
if collect_related:
|
if collect_related:
|
||||||
parents = model._meta.parents
|
if keep_parents:
|
||||||
|
parents = set(model._meta.get_parent_list())
|
||||||
for related in get_candidate_relations_to_delete(model._meta):
|
for related in get_candidate_relations_to_delete(model._meta):
|
||||||
# Preserve parent reverse relationships if keep_parents=True.
|
# Preserve parent reverse relationships if keep_parents=True.
|
||||||
if keep_parents and related.model in parents:
|
if keep_parents and related.model in parents:
|
||||||
|
@ -28,6 +28,10 @@ class RChild(R):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class RChildChild(RChild):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class A(models.Model):
|
class A(models.Model):
|
||||||
name = models.CharField(max_length=30)
|
name = models.CharField(max_length=30)
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
|
|||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
MR, A, Avatar, Base, Child, HiddenUser, HiddenUserProfile, M, M2MFrom,
|
MR, A, Avatar, Base, Child, HiddenUser, HiddenUserProfile, M, M2MFrom,
|
||||||
M2MTo, MRNull, Origin, Parent, R, RChild, Referrer, S, T, User, create_a,
|
M2MTo, MRNull, Origin, Parent, R, RChild, RChildChild, Referrer, S, T,
|
||||||
get_default_r,
|
User, create_a, get_default_r,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -371,6 +371,16 @@ class DeletionTests(TestCase):
|
|||||||
self.assertTrue(R.objects.filter(id=parent_id).exists())
|
self.assertTrue(R.objects.filter(id=parent_id).exists())
|
||||||
self.assertTrue(S.objects.filter(pk=parent_referent_id).exists())
|
self.assertTrue(S.objects.filter(pk=parent_referent_id).exists())
|
||||||
|
|
||||||
|
childchild = RChildChild.objects.create()
|
||||||
|
parent_id = childchild.rchild_ptr.r_ptr_id
|
||||||
|
child_id = childchild.rchild_ptr_id
|
||||||
|
parent_referent_id = S.objects.create(r=childchild.rchild_ptr.r_ptr).pk
|
||||||
|
childchild.delete(keep_parents=True)
|
||||||
|
self.assertFalse(RChildChild.objects.filter(id=childchild.id).exists())
|
||||||
|
self.assertTrue(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):
|
def test_queryset_delete_returns_num_rows(self):
|
||||||
"""
|
"""
|
||||||
QuerySet.delete() should return the number of deleted rows and a
|
QuerySet.delete() should return the number of deleted rows and a
|
||||||
|
Loading…
Reference in New Issue
Block a user