4

I have the following models:

class Branch(models.Model):
    releases = models.ManyToManyField(Release)


class Release(models.Model):
    #fields

What is the default django behavior when you delete a release object (in my case?) Will it delete all branch objects that are only related to that release or not? I am guessing that if don't have it set it up null=True then if I try to delete all releases It will provide me with an IntegrityError correct, because releases will be null empty. If I set it to null=True, then I am guessing it will just leave releases as an empty list if the related object is deleted. Is it possible to delete all related branches when a release is deleted and branch object doesn't have a related object in releases?

e.g

r1 = Release()
r1.save()
r2 = Release()
r2.save()
b1 = Branch()
b1.save()
b1.releases.add(r1)
b2 = Branch()
b2.save()
b2.releases.add(r2)
r1.delete() #this should delete b1 because releases is empty

Is this behavior possible?

Apostolos
  • 7,763
  • 17
  • 80
  • 150

1 Answers1

4

null has no effect in ManyToMany relations.

In Django, M2M relations are represented via an intermediary table, that is automatically generated. Adding null=True/False does not influence the way this intermediary table is built and a parent object can always have no children related.

blank is the option that influences if a parent object is allowed to be created with or without children, but it is not a database level restriction, it's just code level validation.

The way I would implement the cascading delete you are looking for is by using the post_delete signal. Something along the lines of:

from django.db.models.signals import post_delete
from django.dispatch import receiver

class Branch(models.Model):
    releases = models.ManyToManyField(Release)

class Release(models.Model):
    #fields

@receiver(post_delete, sender=Release)
def cascade_delete_branch(sender, instance, **kwargs):
   # code to handle Branch removal
Adrian Ghiuta
  • 1,569
  • 16
  • 29