I'm using a soft delete in my django admin, done like this. The issue is that when I delete a foreign key item, that it doesn't seem to trigger the deletes for all the items it's linked to. Or maybe it does but it's not running the custom def delete I have on my model.
-If I delete a person then they are soft-deleted, but the related account is left untouched.
-If I remove the soft deletes, then when I delete a Person, the Accounts are deleted too which is correct.
So ideally when I delete a Person I'd want it to soft delete the Person and the Accounts referencing the Person to also be soft deleted(marking them inactive).
class Person(models.Model):
description = models.CharField(max_length=100)
def delete(self, *args, **kwargs):
self.active = False
self.deleted_date = datetime.now()
self.save()
class Account(models.Model):
name = models.CharField(max_length=50)
person = models.ForeignKey(Person, null=True, blank=True)
active = models.BooleanField(default=True, editable=False)
objects = SoftDeleteManager()
def delete(self, *args, **kwargs):
self.active = False
self.deleted_date = datetime.now()
self.save()
def __unicode__(self):
return "%s: %s" % (self.type,self.name)
UPDATE: I have updated the question. I had not said that I'm running a soft delete on the Person model. Also added that when the def deletes are not overridden that the cascading deletes work, but when I do override the delete, the cascading doesn't trigger.
Your Person
model is not currently designed for "soft" deletes. When you delete a Person
object, Django will remove all related Account
objects. If you want to soft-delete Person
objects, add a flag for that in the Person
model. Then you need to make sure that your default Account
manager excludes those accounts that are related to a soft-deleted Person object.
Edit:
One approach is making the default manager exclude the objects related to inactive Person objects instead of setting them "deleted":
class AccountManager(models.Manager):
def get_query_set(self):
return self.filter(person__active=True).filter(active=True)
Another approach would be setting your related Account objects "deleted" when a Person object is soft-deleted. For that, you could use a signal. A post-save signal on Person objects would be appropriate I think.