Django soft delete not cascade delete

I am using soft delete in my django admin made like this . The problem is that when I delete a foreign key element, it does not trigger the deletion for all the elements to which it is attached. Or maybe it works, but it doesn’t have the user def delete , which I have on my model.

-If I delete someone, then they will be gently deleted, but the linked account will remain untouched.

-If I delete soft deletions, then when I delete a Face, Accounts are also deleted, which is correct.

Therefore, when I delete the Person, I want him to gently delete the Person and Accounts that refer to the Person, also be soft (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 updated the question. I did not say that I am running soft deletion on the Person model. It is also added that when def deletion is not overridden, that cascading deletions work, but when I redefine deletion, cascading does not start.

+4
source share
2 answers

Your Person model is not currently intended for soft deletions. When you delete a Person object, Django deletes all associated Account objects. If you want to gently remove Person objects, add a flag for the Person model. Then you need to make sure that your default Account manager excludes those accounts that belong to the Person object with soft deletion.

Edit:

  • One approach is that the manager by default excludes objects associated with inactive Person objects, instead of "deleting" them:

      class AccountManager(models.Manager): def get_query_set(self): return self.filter(person__active=True).filter(active=True) 
  • Another approach would be to set related account objects to be β€œdeleted” when the Person object is removed by software. You can use a signal for this. A post-save signal on Person objects would be appropriate, I think.

+2
source

An alternative solution would be to use django-softdelete, the Django package that recently appeared on github: https://github.com/scoursen/django-softdelete

If you use the supplied SoftDeleteObject mixin for your models, deleting them will automatically result in a soft deletion of all related models. Even better, it stores all the models associated with soft deletion, so you can also restore them all with a single refusal to restore.

0
source

All Articles