Django soft delete Model using Managers

I am developer/code-reviewer/debugger/bug-fixer/architect/teacher/builder from dubai, uae
Search for a command to run...

I am developer/code-reviewer/debugger/bug-fixer/architect/teacher/builder from dubai, uae
No comments yet. Be the first to comment.
You Should Tell Yourself

A URL shortener is a proxy service that provides a mapping between the short and full representation of a URL. The short URL has the advantage of being small. The service can also provide useful analy

Listening to the Mel Robbins's podcast on regrets was a 'ear'-opener. One can have reqrets of action or inaction. 4 types of reqrets foundation - should've done the work boldness - should've taken t

We need to create a unique ID generator for our high-traffic web application, generating about 10K IDs/second. The IDs can't simply be monotonically increasing integers, which are good for data access
doing + telling

Below is the soft delete model you can inherit from. It uses an active field which on delete, it will only set to False and not actually delete the records from the overriden delete method. There is a provision available to actually delete records. It can be used in a cronjob to recover space etc.
class SoftDeleteModel(models.Model):
active = models.BooleanField(default=True, db_index=True)
class Meta:
abstract = True
def delete(self, *args, **kwargs): # pylint: disable=unused-argument
if kwargs.pop('hard', False):
return super().delete(*args, **kwargs)
self.active = False
self.save(update_fields=('active',))
return (0, {self._meta.model_name: 0})
One could use a
datetimewhich indicates inactive records if set. It would also record the time when the delete occurred
The ActiveQuerySet overrides the delete method to allow for bulk delete. The corresponding manager uses the override so only active records are included. An InactiveManage which inherits from the default Manger is included for completeness.
class ActiveQuerySet(models.QuerySet):
def delete(self, *args, **kwargs):
if kwargs.pop('hard', False):
return super().delete(*args, **kwargs)
return self.update(active=False)
class ActiveManager(models.Manager):
def get_queryset(self):
return ActiveQuerySet(self.model, using=self._db).exclude(active=False)
class InActiveManager(models.Manager):
def get_queryset(self):
return super().get_queryset().exclude(active=True)
Here's and example of it all put together.
from django.db import models
class Textbooks(models.Model, SoftDeleteModel):
id = models.UUIDField(db_index=True)
objects = ActiveManager()
deleted_objects = InActiveManager()
all_objects = models.Manager()
Notice that the default
objectsis overriden to only provide active records for all ORM actions.