mirror of
https://github.com/django/django.git
synced 2025-10-26 23:26:08 +00:00
Fixed #21961 -- Added support for database-level delete options for ForeignKey.
Thanks Simon Charette for pair programming. Co-authored-by: Nick Stefan <NickStefan12@gmail.com> Co-authored-by: Akash Kumar Sen <71623442+Akash-Kumar-Sen@users.noreply.github.com> Co-authored-by: Simon Charette <charette.s@gmail.com>
This commit is contained in:
@@ -34,11 +34,16 @@ from .models import (
|
||||
RChild,
|
||||
RChildChild,
|
||||
Referrer,
|
||||
RelatedDbOption,
|
||||
RelatedDbOptionGrandParent,
|
||||
RelatedDbOptionParent,
|
||||
RProxy,
|
||||
S,
|
||||
SetDefaultDbModel,
|
||||
T,
|
||||
User,
|
||||
create_a,
|
||||
create_related_db_option,
|
||||
get_default_r,
|
||||
)
|
||||
|
||||
@@ -76,18 +81,48 @@ class OnDeleteTests(TestCase):
|
||||
a = A.objects.get(pk=a.pk)
|
||||
self.assertIsNone(a.setnull)
|
||||
|
||||
def test_db_setnull(self):
|
||||
a = create_related_db_option("db_setnull")
|
||||
a.db_setnull.delete()
|
||||
a = RelatedDbOption.objects.get(pk=a.pk)
|
||||
self.assertIsNone(a.db_setnull)
|
||||
|
||||
def test_setdefault(self):
|
||||
a = create_a("setdefault")
|
||||
a.setdefault.delete()
|
||||
a = A.objects.get(pk=a.pk)
|
||||
self.assertEqual(self.DEFAULT, a.setdefault.pk)
|
||||
|
||||
@skipUnlessDBFeature("supports_on_delete_db_default")
|
||||
def test_db_setdefault(self):
|
||||
# Object cannot be created on the module initialization, use hardcoded
|
||||
# PKs instead.
|
||||
r = RelatedDbOptionParent.objects.create(pk=2)
|
||||
default_r = RelatedDbOptionParent.objects.create(pk=1)
|
||||
set_default_db_obj = SetDefaultDbModel.objects.create(db_setdefault=r)
|
||||
set_default_db_obj.db_setdefault.delete()
|
||||
set_default_db_obj = SetDefaultDbModel.objects.get(pk=set_default_db_obj.pk)
|
||||
self.assertEqual(set_default_db_obj.db_setdefault, default_r)
|
||||
|
||||
def test_setdefault_none(self):
|
||||
a = create_a("setdefault_none")
|
||||
a.setdefault_none.delete()
|
||||
a = A.objects.get(pk=a.pk)
|
||||
self.assertIsNone(a.setdefault_none)
|
||||
|
||||
@skipUnlessDBFeature("supports_on_delete_db_default")
|
||||
def test_db_setdefault_none(self):
|
||||
# Object cannot be created on the module initialization, use hardcoded
|
||||
# PKs instead.
|
||||
r = RelatedDbOptionParent.objects.create(pk=2)
|
||||
default_r = RelatedDbOptionParent.objects.create(pk=1)
|
||||
set_default_db_obj = SetDefaultDbModel.objects.create(
|
||||
db_setdefault_none=r, db_setdefault=default_r
|
||||
)
|
||||
set_default_db_obj.db_setdefault_none.delete()
|
||||
set_default_db_obj = SetDefaultDbModel.objects.get(pk=set_default_db_obj.pk)
|
||||
self.assertIsNone(set_default_db_obj.db_setdefault_none)
|
||||
|
||||
def test_cascade(self):
|
||||
a = create_a("cascade")
|
||||
a.cascade.delete()
|
||||
@@ -359,6 +394,22 @@ class DeletionTests(TestCase):
|
||||
self.assertNumQueries(5, s.delete)
|
||||
self.assertFalse(S.objects.exists())
|
||||
|
||||
def test_db_cascade(self):
|
||||
related_db_op = RelatedDbOptionParent.objects.create(
|
||||
p=RelatedDbOptionGrandParent.objects.create()
|
||||
)
|
||||
RelatedDbOption.objects.bulk_create(
|
||||
[
|
||||
RelatedDbOption(db_cascade=related_db_op)
|
||||
for _ in range(2 * GET_ITERATOR_CHUNK_SIZE)
|
||||
]
|
||||
)
|
||||
with self.assertNumQueries(1):
|
||||
results = related_db_op.delete()
|
||||
self.assertEqual(results, (1, {"delete.RelatedDbOptionParent": 1}))
|
||||
self.assertFalse(RelatedDbOption.objects.exists())
|
||||
self.assertFalse(RelatedDbOptionParent.objects.exists())
|
||||
|
||||
def test_instance_update(self):
|
||||
deleted = []
|
||||
related_setnull_sets = []
|
||||
|
||||
Reference in New Issue
Block a user