Registry / web-framework / django-safedelete

django-safedelete

JSON →
library1.5.0pypypi✓ verified 24d ago

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.

pip install django-safedelete
INSTALL
IMPORT
SIG · DJANGO-SAFEDELETE
D
django-safedelete
web-frameworkpythonv1.5.0
Install
3.6s avg
Import
Disk
67MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.5.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.000s · 67.7MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 3.6s · import 0.000s · 68MB
67MB installed
● package 67MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

SafeDeleteModel
from safedelete.models import SafeDeleteModel
from safedelete.models import SafeDeleteModel

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
Debug
Known issues
breakingThe `SafeDeleteMixin` class was renamed to `SafeDeleteModel` in version 0.4.0. Using `SafeDeleteMixin` is deprecated and will raise a warning.
fix
Update your models to inherit from `safedelete.models.SafeDeleteModel` instead of `SafeDeleteMixin`.
affects: 0.4.0+
breakingThe `deleted` field on `SafeDeleteModel` changed from a `BooleanField` to a `DateTimeField` in version 0.4.0. This can break existing queries or logic relying on a boolean check.
fix
Adjust any code that checks `obj.deleted` to check `obj.deleted is not None` or `obj.deleted__isnull=False` in queries, to account for the `DateTimeField` behavior.
affects: 0.4.0+
breakingSignificant Django and Python version compatibility changes can occur between minor and major versions of django-safedelete. For instance, version 1.3.0 dropped support for Django < 3.2 and Python 3.6, and version 1.4.0 dropped support for Django 3.2, 4.0, and 4.1.
fix
Always check the `django-safedelete` changelog or PyPI page for supported Django and Python versions before upgrading, especially if your project relies on older environments.
affects: 1.3.0, 1.4.0+
gotchaBy default, related objects (via `ForeignKey` or `OneToOneField`) that are soft-deleted might still be accessible through direct relation traversal (e.g., `article.author` if `author` is deleted). This can lead to unexpected behavior where 'deleted' objects are still retrieved.
fix
Set `_safedelete_visibility = DELETED_INVISIBLE` (the default for managers) on your managers or models, and understand that direct access can still bypass this. For stricter control, you might need to override managers for related fields or use `SafeDeleteQueryset.visible()` or `SafeDeleteQueryset.undeleted()` in your queries.
affects: All versions
gotchaIf the `SAFE_DELETE_INTERPRET_UNDELETED_OBJECTS_AS_CREATED` setting is enabled, Django's `update_or_create()` method will return `(object, True)` (indicating 'created') when an object was soft-deleted and subsequently 'revived' or undeleted, rather than a truly new object being created. This can be misleading.
fix
Be aware of this setting's effect when using `update_or_create()`. If you need to distinguish between a new creation and an undeletion, inspect the object's `deleted` field or use custom logic.
affects: All versions
Upgrade
Version history
1.5.0latest on PyPI · released Aug 17, 2026
Audit
Dependencies
DjangorequiredCore framework dependency; version 1.4.x supports Django 4.2 and 5.0, and Python 3.8-3.11.
packagingrequiredUsed for version parsing and compatibility checks.
Agent activity
32 hits · last 30 days
node
28
Amazon
1
OpenAI (training)
1
Resources