Yet another approach to provide soft (logical) delete or masking (thrashing) django models instead of deleting them physically from db.
To create non-deletable model just inherit it form the PermanentModel.:
class MyModel(PermanentModel): pass
It automatically changes delete behaviour, to hide model instead of deleting. restore() method.:
>>> a = MyModel.objects.create(pk=1) >>> b = MyModel.objects.create(pk=2) >>> MyModel.objects.count() 2 >>> a.delete() >>> MyModel.objects.count() 1
To recover model just call its restore method.:
>>> a.restore() >>> MyModel.objects.count() 2
User Force kwarg to enforce physical deletion.:
>>> a.delete(force=True) # Will act as the default django delete >>> MyModel._base_manager.count() 0
If you need to restore deleted model instead of creating the same use restore_on_create attribute.:
class MyModel(PermanentModel): class Permanent: restore_on_create = True
In this case QuerySet provides check existence of same attributes object and restores it if it was removed, creates a new if not.
It changes default model manager to ignore deleted objects. And adds deleted_objects manager to find the last ones.:
>>> MyModel.objects.count() 2 >>> a.delete() >>> MyModel.objects.count() 1 >>> MyModel.deleted_objects.count() 1 >>> MyModel.all_objects.count() 2 >>> MyModel._base_manager.count() 2
Query set delete method will act as the default django delete, with the one exception - all related PermanentModel children will be marked as deleted, the usual models will be deleted physically:
You can still force django query set physical deletion:
Using custom querysets (requires django-model-utils)
Inherit your query set from PermanentQuerySet:
class ServerFileQuerySet(PermanentQuerySet) pass
Wrap it in the permanent_queryset or deleted_queryset in you model manager declaration:
class MyModel(PermanentModel) objects = MultiPassThroughManager(ServerFileQuerySet, NonDeletedQuerySet) deleted_objects = MultiPassThroughManager(ServerFileQuerySet, DeletedQuerySet) all_objects = MultiPassThroughManager(ServerFileQuerySet, PermanentQuerySet)
- Check existence of the object.
- Restore it was deleted.
- Create new one, if it wasn't ever created.
By default field is named removed, but you can override it by PERMANENT_FIELD variable in your settings.py.:
PERMANENT_FIELD = 'deleted'
Django min 1.6.x required. To cover Django 1.5 needs use 0.1.4 branch.