Django reusable app for revision-based undo functionality with django-simple-history
Project description
django-undo-revision
A Django reusable app for revision-based undo functionality, built on top of django-simple-history.
How it works
Every mutation is wrapped in a revision — a unit that can be rolled back atomically with a single undo_last_revision(project) call. A revision automatically groups all historical records (creates, updates, deletes) made within its context.
Installation
pip install django-undo-revision
Add to INSTALLED_APPS:
INSTALLED_APPS = [
...
"django.contrib.contenttypes",
"simple_history",
"undo_revision",
]
Run migrations:
python manage.py migrate
Configuration
In settings.py, set the project model (the entity revisions are scoped to):
UNDO_REVISION_PROJECT_MODEL = "myapp.Project" # required
# URL kwarg used by UndoRevisionMixin to extract the project id
UNDO_REVISION_PROJECT_URL_KWARG = "project_id"
# HTTP methods that should open a revision (default: all mutating methods)
UNDO_REVISION_HTTP_METHODS = ["post", "put", "patch", "delete"]
Usage
1. Inherit models from HistoricalModel
from undo_revision.models import HistoricalModel
class Document(HistoricalModel):
title = models.CharField(max_length=255)
body = models.TextField()
HistoricalModel wires up RevisionHistoricalRecords (an extension of HistoricalRecords) and RevisionQuerySet.
2. Open a revision around mutations
from undo_revision.revision.context import open_revision
with open_revision(project_id=project.id):
doc.title = "New title"
doc.save()
other_obj.delete()
# All changes inside the block are grouped into one revision
If no changes were recorded inside the block, the revision is deleted automatically.
3. Undo the last revision
from undo_revision.revision.undo import undo_last_revision, RevisionNotFoundError
try:
undo_last_revision(project)
except RevisionNotFoundError:
print("Nothing to undo")
The function fetches the latest revision for the project and rolls back all its changes in reverse chronological order.
4. Auto-open revisions via mixin (DRF / CBV)
from undo_revision.revision.mixins import UndoRevisionMixin
from rest_framework.viewsets import ModelViewSet
class DocumentViewSet(UndoRevisionMixin, ModelViewSet):
project_url_kwarg = "project_id" # URL kwarg carrying the project id
...
The mixin wraps all mutating methods (post, put, patch, delete) with open_revision automatically.
5. Bulk operations
RevisionQuerySet exposes helpers for bulk mutations:
MyModel.objects.bulk_create_with_history(objs)
MyModel.objects.bulk_update_with_history(objs, fields=["title"])
# Skip history (not tracked in any revision)
MyModel.objects.bulk_create_without_history(objs)
MyModel.objects.bulk_update_without_history(objs, fields=["title"])
MyModel.objects.create_without_history(title="...")
MyModel.objects.filter(...).delete_without_history()
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_undo_revision-1.0.2.tar.gz.
File metadata
- Download URL: django_undo_revision-1.0.2.tar.gz
- Upload date:
- Size: 26.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b0632a6f6a529cbae92f89de29b2cddd2eed9d9fcb1a6707d201dfc56e38681
|
|
| MD5 |
a01bd85efe66ef0d52e9611af53c17f0
|
|
| BLAKE2b-256 |
7ff3383616a844dea28ec71bd0ce405bde986f7b506cb97bc627884b0caca8f6
|
File details
Details for the file django_undo_revision-1.0.2-py3-none-any.whl.
File metadata
- Download URL: django_undo_revision-1.0.2-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f2459b92a6fdb949c6cc2fa521ee98408d0f0658e18bbf04fbfb8f2df6f17a80
|
|
| MD5 |
329ec61960f8b876c9056f04b755498c
|
|
| BLAKE2b-256 |
99d4d2e98bf803d192d945480ddbd0919dc4d4eaa5025a883a45dc2716456095
|