Django SafeDelete

1.4.1 · active · verified Sun Apr 12

Django SafeDelete is an active library (current version 1.4.1) that provides soft deletion functionality for Django models, allowing objects to be masked from the database instead of permanently deleted. This enables recovery of 'deleted' data and aids in auditing. It offers various deletion policies and integrates with Django's ORM and Admin interface. Releases occur periodically, with significant updates often tied to Django version compatibility.

Warnings

Install

Imports

Quickstart

To use django-safedelete, make your model inherit from `SafeDeleteModel` and optionally set a `_safedelete_policy`. By default, `SOFT_DELETE` is used. Objects are then soft-deleted by calling `.delete()` and can be queried using `Article.all_objects` or `Article.deleted_objects`. To undelete, use the `.undelete()` method. You can force a hard delete using `force_policy=SafeDeleteModel.HARD_DELETE`.

import os
import django
from django.db import models
from safedelete.models import SafeDeleteModel, SOFT_DELETE

# Configure Django settings minimally for a runnable example
os.environ.setdefault('DJANGO_SETTINGS_MODULE', __name__)
django.setup()

class Article(SafeDeleteModel):
    _safedelete_policy = SOFT_DELETE
    title = models.CharField(max_length=200)
    content = models.TextField()
    published_date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

# Example Usage:
# Make sure Django is set up and models are migrated (not covered here)

# Create an object
article = Article.objects.create(title='My First Article', content='This is some content.')
print(f"Created: {article}") # cite: 5

# Soft delete the object
article.delete()
print(f"Article soft-deleted. Is it deleted? {article.deleted is not None}") # cite: 5

# It won't appear in default queries
print(f"Visible articles count: {Article.objects.count()}") # Should be 0

# Access soft-deleted objects using the all_objects manager
all_articles = Article.all_objects.all()
print(f"All articles (including deleted): {all_articles.count()}") # Should be 1 # cite: 5

# Filter for only deleted objects
deleted_articles = Article.deleted_objects.all()
print(f"Only deleted articles: {deleted_articles.count()}") # Should be 1

# Undelete the object
deleted_article = Article.deleted_objects.get(pk=article.pk)
deleted_article.undelete()
print(f"Article undeleted. Is it deleted? {deleted_article.deleted is not None}")
print(f"Visible articles count after undelete: {Article.objects.count()}") # Should be 1

# Hard delete (bypassing soft delete)
hard_delete_article = Article.objects.create(title='To be hard deleted', content='Ephemeral content.')
hard_delete_article.delete(force_policy=SafeDeleteModel.HARD_DELETE)
print(f"Hard-deleted article count: {Article.all_objects.filter(pk=hard_delete_article.pk).count()}") # Should be 0

view raw JSON →