[Django] #27585: ManyToMany relationship is cascading delete after being detached

4 views
Skip to first unread message

Django

unread,
Dec 9, 2016, 12:12:43 PM12/9/16
to django-...@googlegroups.com
#27585: ManyToMany relationship is cascading delete after being detached
-------------------------------------+-------------------------------------
Reporter: Teresa | Owner: nobody
Type: Bug | Status: new
Component: Database | Version: 1.8
layer (models, ORM) | Keywords: ManyToMany,
Severity: Normal | cascade, delete, remove
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Given two models A and B that have a many-to-many relationship, removing
all of the As from a model B, then deleting B results in all of the As
that should now be detached from B being deleted. This is happening inside
of a single transaction, using an SQLite database backend, as well as a
MySQL backend.

Below is code that will reproduce the issue:

{{{
class A(models.Model):
bs = models.ManyToManyField(B, related_name='as')

class B(models.Model):
...

def delete_b_without_deleting_as(b):
with transaction.atomic():
to_be_orphaned_as = [a for a in b.as.all()]
for a in to_be_orphaned_as:
b.as.remove(a)
b.delete()
}}}

This results in both 'b' and all of the 'a's that had been a part of
b.as.all() to be deleted from the database.

The expected behaviour would be for b.delete() to not cascade as it is a
ManyToMany field, and in addition all of the 'a's have been detached from
the relationship with 'b'. There is no reason for deleting 'b' to cascade
and delete models that no longer have any relationship with 'b'.

--
Ticket URL: <https://code.djangoproject.com/ticket/27585>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Dec 9, 2016, 12:21:24 PM12/9/16
to django-...@googlegroups.com
#27585: ManyToMany relationship is cascading delete after being detached
-------------------------------------+-------------------------------------
Reporter: Teresa | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: ManyToMany, | Triage Stage:
cascade, delete, remove | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Teresa):

* status: new => closed
* resolution: => invalid


--
Ticket URL: <https://code.djangoproject.com/ticket/27585#comment:1>

Django

unread,
Dec 9, 2016, 2:55:09 PM12/9/16
to django-...@googlegroups.com
#27585: ManyToMany relationship is cascading delete after being detached
-------------------------------------+-------------------------------------
Reporter: Teresa | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution:
Keywords: ManyToMany, | Triage Stage:
cascade, delete, remove | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Teresa):

* status: closed => new
* resolution: invalid =>


Comment:

An additional detail:

The models also have a ManyToOne foreign key constraint. But when that
relationship has also been removed, the now unattached 'a's are deleted.

--
Ticket URL: <https://code.djangoproject.com/ticket/27585#comment:2>

Django

unread,
Dec 9, 2016, 3:26:28 PM12/9/16
to django-...@googlegroups.com
#27585: ManyToMany relationship is cascading delete after being detached
-------------------------------------+-------------------------------------
Reporter: Teresa | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution:
Keywords: ManyToMany, | Triage Stage:
cascade, delete, remove | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham):

Could you please provide a sample app with models and tests we could
download to reproduce? The example code doesn't run as `b.as.all()` is a
`SyntaxError`.

--
Ticket URL: <https://code.djangoproject.com/ticket/27585#comment:3>

Django

unread,
Dec 9, 2016, 3:31:01 PM12/9/16
to django-...@googlegroups.com
#27585: ManyToMany relationship is cascading delete after being detached
-------------------------------------+-------------------------------------
Reporter: Teresa | Owner: nobody
Type: Bug | Status: closed

Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution: invalid

Keywords: ManyToMany, | Triage Stage:
cascade, delete, remove | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Teresa):

* status: new => closed
* resolution: => invalid


--
Ticket URL: <https://code.djangoproject.com/ticket/27585#comment:4>

Django

unread,
May 22, 2020, 5:21:36 PM5/22/20
to django-...@googlegroups.com
#27585: ManyToMany relationship is cascading delete after being detached
-------------------------------------+-------------------------------------
Reporter: Teresa | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: ManyToMany, | Triage Stage:
cascade, delete, remove | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Matt):

This problem just happened to me on Django 2.2.12 in a migration. e.g.

{{{
Category = apps.get_model('blog', 'Category')

cat = Category.objects.filter(name='Cat A').first()

for article in list(cat.article_set.all()):
cat.article_set.remove(article)

# This deleted all articles that were in the category but were already
removed()
cat.delete()
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/27585#comment:5>

Reply all
Reply to author
Forward
0 new messages