django-resurrected provides soft-delete functionality for Django projects.
Instead of permanently removing objects, it marks them as “removed,” making them easy to restore later.
The package supports relation-aware deletion and restoration, along with configurable retention.
pip install django-resurrectedInherit from SoftDeleteModel to enable soft-deletion and restoration:
from django.db import models
from django_resurrected.models import SoftDeleteModel
class Author(SoftDeleteModel):
name = models.CharField(max_length=100)
class Book(SoftDeleteModel):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
class BookMeta(SoftDeleteModel):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
format = models.CharField(max_length=20)Each manager now has:
.objects— only active (not removed).removed_objects— only soft-deleted.all_objects— all records (active + removed)
Removing a parent will also remove its related children:
>>> author = Author.objects.create(name="Frank")
>>> book = Book.objects.create(author=author, title="Dune")
>>> meta = BookMeta.objects.create(book=book, format="ebook")
>>> Author.objects.count()
1
>>> Book.objects.count()
1
>>> BookMeta.objects.count()
1
>>> author.remove()
(3, {'test_app.Author': 1, 'test_app.Book': 1, 'test_app.BookMeta': 1})
>>> Author.objects.count()
0
>>> Book.objects.count()
0
>>> BookMeta.objects.count()
0>>> author.restore()
(1, {'test_app.Author': 1})
>>> Author.objects.count()
1
>>> Book.objects.count()
0
>>> BookMeta.objects.count()
0>>> author.restore(with_related=True)
(3, {'test_app.Author': 1, 'test_app.Book': 1, 'test_app.BookMeta': 1})
>>> Author.objects.count()
1
>>> Book.objects.count()
1
>>> BookMeta.objects.count()
1>>> author.remove()
(3, {'test_app.Author': 1, 'test_app.Book': 1, 'test_app.BookMeta': 1})
>>> book.restore()
(2, {'test_app.Book': 1, 'test_app.Author': 1})
>>> Author.objects.count()
1
>>> Book.objects.count()
1
>>> BookMeta.objects.count()
0You can customize the retention period by setting the retention_days attribute on your model. Set it to None to keep objects indefinitely.
# your_app/models.py
from django_resurrected.models import SoftDeleteModel
class ImportantDocument(SoftDeleteModel):
# Keep forever
retention_days = None
content = models.TextField()
class TemporaryFile(SoftDeleteModel):
# Keep for one week
retention_days = 7
data = models.BinaryField()To permanently remove objects that have exceeded their retention limit, call purge():
>>> TemporaryFile.removed_objects.all().purge()This project is licensed under the MIT License.