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.
* status: new => closed
* resolution: => invalid
--
Ticket URL: <https://code.djangoproject.com/ticket/27585#comment:1>
* 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>
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>
* status: new => closed
* resolution: => invalid
--
Ticket URL: <https://code.djangoproject.com/ticket/27585#comment:4>
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>