PetOwner and a
class PetOwner(models.Model): name = models.CharField() class Pet(models.Model): owner = models.ForeignKey('PetOwner', on_delete=models.CASCADE) alive = models.BooleanField(default=True)
I would like it to be possible to delete PetOwners, but only if all theiry associated Pets are not alive anymore. If that is the case, the PetOwner can be deleted and all his associated pets are also deleted (cascade semantics).
Is that possible?
You are talking about to set a ‘business rule’. You can write your ‘business rules’ in several places, for example, in each view or process that delete
Also, you can override
delete method on model. Take in mind:
Overridden model methods are not called on bulk operations
Note that the delete() method for an object is not necessarily called when deleting objects in bulk using a QuerySet or as a result of a cascading delete. To ensure customized delete logic gets executed, you can use pre_delete and/or post_delete signals.
This is how to override delete:
from django.core.exceptions import PermissionDenied class PetOwner(models.Model): # ... def delete(self): has_pets_alive = self.pet_set.filter(alive=True).exists() if has_pets_alive: raise PermissionDenied("This owner has pets alive") super(PetOwner, self).delete()
Another solution are signals:
from django.db.models.signals import pre_delete from django.dispatch import receiver @receiver(pre_delete, sender=PetOwner) def check_pets_alive(sender, instance, **kwargs): has_pets_alive = instance.pet_set.filter(alive=True).exists() if has_pets_alive: raise PermissionDenied("This owner has pets alive")
Answered By – dani herrera