[Fixed]-How can I easily mark records as deleted in Django models instead of actually deleting them?

13👍

Warning: this is an old answer and it seems that the documentation is recommending not to do that now: https://docs.djangoproject.com/en/dev/topics/db/managers/#don-t-filter-away-any-results-in-this-type-of-manager-subclass

Django offers out of the box the exact mechanism you are looking for.

You can change the manager that is used for access through related objects. If you new custom manager filters the object on a boolean field, the object flagged inactive won’t show up in your requests.

See here for more details :
http://docs.djangoproject.com/en/dev/topics/db/managers/#using-managers-for-related-object-access

4👍

Nice question, I’ve been wondering how to efficiently do this myself.

I am not sure if this will do the trick, but django-reversion seems to do what you want, although you probably want to examine to see how it achieves this goal, as there are some inefficient ways to do it.

Another thought would be to have the dreaded boolean flag on your Models and then creating a custom manager that automatically adds the filter in, although this wouldn’t work for searches across different Models. Yet another solution suggested here is to have duplicate models of everything, which seems like overkill, but may work for you. The comments there also discuss different options.

I will add that for the most part I don’t consider any of these solutions worth the hassle; I usually just suck it up and filter my searches on the boolean flag. It avoids many issues that can come up if you try to get too clever. It is a pain and not very DRY, of course. A reasonable solution would be a mixture of the Custom manager while being aware of its limitations if you try searching a related model through it.

3👍

I think using a boolean ‘is_active’ flag is fine – you don’t need to cascade the flag to related entries at the db level, you just need to keep referring to the status of the parent. This is what happens with contrib.auth’s User model, remember – marking a user as not is_active doesn’t prompt django to go through related models and magically try to deactivate records, rather you just keep checking the is_active attribute of the user corresponding to the related item.

For instance if each user has many bookmarks, and you don’t want an inactive user’s bookmarks to be visible, just ensure that bookmark.user.is_active is true. There’s unlikely to be a need for an is_active flag on the bookmark itself.

👤ozan

3👍

Here’s a quick blog tutorial from Greg Allard from a couple of years ago, but I implemented it using Django 1.3 and it was great. I added methods to my objects named soft_delete, undelete, and hard_delete, which set self.deleted=True, self.deleted=False, and returned self.delete(), respectively.

A Django Model Manager for Soft Deleting Records and How to Customize the Django Admin

0👍

There are several packages which provide this functionality: https://www.djangopackages.com/grids/g/deletion/

I’m developing one https://github.com/meteozond/django-permanent/
It replaces default Manager and QuerySet delete methods to bring in logical deletion.
It completely shadows default Django delete methods with one exception – marks models which are inherited from PermanentModel instead of deletion, even if their deletion caused by relation.

Leave a comment