How to use Soft Delete in Django?

Published On: 06/01/2023 | Category: Django


Hi Dev,

In this example, we will discuss about how to use soft delete in django. if you want to see example of django soft delete example then you are come to right place. you will learn django model soft delete example. we will help you to give example of soft delete in django.

You may want to remove something from your database without actually removing it. You want to keep it in case you want to restore it in the future. this is pattern called soft-delete.

Here i will give you we will help you to give example of how to use soft delete in django. So let's see the bellow example:

Step 1: Create a Project

In this step, we’ll create a new django project using the django-admin. Head back to your command-line interface and run the following command:

django-admin startproject myproject
Step 2: Create a App
cd myproject
django-admin startapp base

Step 3: Update settings.py

Next, you need to add it in the settings.py file as follows:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'base', #new
]

Step 4: Create a Model

Now go for We'll start by creating a base SoftDeleteModelthat the rest of our models can inherit.

base/models.py
from django.db import models
from django.db.models.deletion import CASCADE

class SoftDeleteModel(models.Model):

    is_deleted = models.BooleanField(default=False)

    def soft_delete(self):
        self.is_deleted = True
        self.save()

    def restore(self):
        self.is_deleted = False
        self.save()

    class Meta:
        abstract = True


class Article(SoftDeleteModel):

    title = models.CharField(max_length=32)
    content = models.CharField(max_length=255)
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="articles")

Next, we can fetch the records our database filtered by is_deleted there are exclude the records that have been soft-deleted.

Article.objects.filter(is_deleted=False)

SO, next open your django shell follow below command and lets try out.

python manage.py shell

Import the models:

from django.contrib.auth.models import User
from base.models import Article

First of all we need to create a user.

bhavesh = User.objects.create_user('bhavesh', '[email protected]', 'password')

Next, create a some article following code.

my_article = Article.objects.create(author=bhavesh, title="Python", content="Python Developer")
another_article = Article.objects.create(author=bhavesh, title="Django", content="Django Developer")

You are now ready to soft delete and restore articles:

my_article.soft_delete()
my_article.restore()

You can query for all articles, whether they have been soft deleted or not:

Article.objects.all()

So, you can filter records in not have been soft-deleted.

Article.objects.filter(is_deleted=False)

Create a Soft-Delete Manager

Now we next create soft delete model manager now current scenario main disadvantages of every time is_deleted=False each time write query.

base/models.py
from django.db import models
from django.db.models.deletion import CASCADE


class SoftDeleteManager(models.Manager):

    def get_queryset(self):
        return super().get_queryset().filter(is_deleted=False)

class SoftDeleteModel(models.Model):

    is_deleted = models.BooleanField(default=False)
    objects = models.Manager()
    undeleted_objects = SoftDeleteManager()

    def soft_delete(self):
        self.is_deleted = True
        self.save()

    def restore(self):
        self.is_deleted = False
        self.save()

    class Meta:
        abstract = True

So, next we can simply rewrite the query.

Article.undeleted_objects.all()

To, fetch a queryset undeleted articles.

Article.objects.all()

Manage foreign key relationship using soft delete.

Article.objects.filter(user=bhavesh, is_deleted=False)
bhavesh.articles.all()

Additional Data Store

In Django app, more thing we can do. Knowing whether or not a record has been soft deleted is useful, but it would also be nice to know when the record was soft deleted. We can accomplish this by adding a new an attribute deleted_at to our SoftDeleteModel:

deleted_at = models.DateTimeField(null=True, default=None)

We can also update our soft_delete and restore methods as follows:

def soft_delete(self):
    self.deleted_at = timezone.now()
    self.save()

def restore(self):
    self.deleted_at = None
    self.save()

Our rewritten SoftDeleteModel now looks like this:

class SoftDeleteModel(models.Model):

    deleted_at = models.DateTimeField(null=True, default=None)
    objects = SoftDeleteManager()
    all_objects = models.Manager()

    def soft_delete(self):
        self.deleted_at = timezone.now()
        self.save()

    def restore(self):
        self.deleted_at = None
        self.save()

    class Meta:
        abstract = True

And our rewritten SoftDeleteManager looks like this:

class SoftDeleteManager(models.Manager):

    def get_queryset(self):
        return super().get_queryset().filter(deleted_at__isnull=True)

Now, we can also see the exact date and time at which our record was soft deleted:

my_article.deleted_at

I Hope It will help you....