Search code examples
pythondjangodatabasebulkupdate

Bulk clear ManyToMany after object traversal


I have the following data models:

class ArticleSet(Model):
    pass

class Article(Model):
    article_set = ForeignKey(ArticleSet, related_name = 'articles')
    attachments = ManyToManyField(Attachment, related_name='articles')

Now I have an ArticleSet and want to clear (not delete!) all attachments from them. The following will work:

for article in article_set.articles.all():
    article.attachments.clear()

However, this will cause a database query per article in the article_set. Is there a way to do the same in a single call to the database? I am using Django 1.11.

p.s. This question is related to How do I remove multiple objects in a ManyToMany relationship based on a filter?, but in that question there is no model traversal before deleting relations.


Solution

  • You can access the ManyToMany table by using the through attribute. By deleting items from that table you are removing the relationship. So try:

    m2m_model = Article.attachments.through
    m2m_model.objects.filter(article__article_set=article_set).delete()
    

    That will run in one query.