Registry / web-framework / django-reversion

django-reversion

JSON →
library6.3.0pypypi✓ verified 24d ago

Django Reversion is an actively maintained extension to the Django web framework that provides comprehensive version control for model instances. It allows developers to effortlessly track, revert, and manage changes made to their data, including the ability to recover deleted objects. The current version is 6.1.0, with a regular release cadence addressing compatibility and new features.

pip install django-reversion
INSTALL
IMPORT
SIG · DJANGO-REVERSION
D
django-reversion
web-frameworkpythonv6.3.0
Install
3.5s avg
Import
726ms
Disk
66MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v6.3.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.752s · 66.9MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 3.5s · import 0.700s · 67MB
66MB installed
● package 66MB
Code
Verified usage

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

register
from reversion import register
Decorator for enabling version control on models.
VersionAdmin
from reversion.admin import VersionAdmin
Provides version history and recovery in the Django admin interface.
create_revision
from reversion import create_revision
Context manager or decorator to group changes into a single revision.
get_for_object
from reversion import get_for_object
from reversion.models import Version; Version.objects.get_for_object(obj)
The higher-level `reversion.get_for_object` is generally preferred over direct `Version.objects` queries.

To get started, install `django-reversion` and add it to your `INSTALLED_APPS`. Then, register your models using the `@reversion.register()` decorator or inherit `VersionAdmin` in your `admin.py` for automatic integration. The `create_revision()` context manager or decorator is used to group multiple changes into a single historical revision, and `get_for_object()` allows programmatic access to an object's version history.

import os # settings.py (simplified for demonstration) INSTALLED_APPS = [ # ... other apps 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'reversion', 'myapp', ] # myapp/models.py from django.db import models from reversion import register @register() class MyModel(models.Model): name = models.CharField(max_length=100) value = models.IntegerField(default=0) def __str__(self): return self.name # myapp/admin.py from django.contrib import admin from reversion.admin import VersionAdmin from .models import MyModel @admin.register(MyModel) class MyModelAdmin(VersionAdmin): pass # Example usage in a view or management command (assuming MyModel is created) from django.db import transaction from reversion import create_revision, set_comment def update_my_model(obj_id, new_name, comment): with create_revision(): set_comment(comment) with transaction.atomic(): obj = MyModel.objects.get(id=obj_id) obj.name = new_name obj.save() # Other related model saves can go here within the same revision block # reversion.add_to_revision(related_obj) # To retrieve history: from reversion import get_for_object my_instance = MyModel.objects.first() # Get an existing instance if my_instance: versions = get_for_object(my_instance).order_by('-revision__date_created') for version in versions: print(f"Version {version.pk}: {version.field_dict['name']} (Comment: {version.revision.comment}, User: {version.revision.user})")
Debug
Known issues
breakingIn `v6.0.0`, the custom `pre_revision_commit` and `post_revision_commit` signals were removed. Users should now leverage Django's standard `pre_save` and `post_save` signals on the `Revision` model for similar functionality.
fix
Replace `reversion.signals.pre_revision_commit` or `post_revision_commit` signal connections with Django's `django.db.models.signals.pre_save` or `post_save` signals connected to the `reversion.models.Revision` model.
affects: >=6.0.0
breakingAs of `v5.0.0`, support for Python 3.6 was dropped. The library now officially requires Python 3.9 or later, and Django 4.2 or later, as per `v6.1.0` requirements.
fix
Upgrade your Python environment to 3.9+ and your Django version to 4.2+ before upgrading to recent `django-reversion` versions.
affects: >=5.0.0 (Python), >=6.1.0 (Django)
gotchaChanges to your model's schema (e.g., removing fields) can lead to `reversion.errors.RevertError: Could not load <Foo: bar> - incompatible version data` when attempting to restore older versions. This is because `django-reversion` stores versions as JSON, and schema migrations do not update this historical data.
fix
After significant model schema changes, it is often necessary to clear out old revision data for the affected models. Adding new fields is usually fine, but removing fields is problematic. Consider creating data migrations to handle or delete incompatible historical data.
affects: All versions
gotchaBulk update operations (e.g., `QuerySet.update()`) do not trigger Django's `post_save` signals, which `django-reversion` relies on to create revisions. Consequently, changes made via bulk operations will not be recorded in version history automatically.
fix
To version changes from bulk operations, wrap them explicitly within a `reversion.create_revision()` context manager and manually add affected objects using `reversion.add_to_revision()` if granular control is needed, or iterate and save objects individually.
affects: All versions
gotchaThe `reversion.RegistrationError: class 'myapp.MyModel' has already been registered with Reversion` commonly occurs due to models.py being imported twice, often caused by relative import statements in your codebase.
fix
Convert all relative import statements in your Django apps to absolute imports to ensure `models.py` files are not unintentionally imported multiple times.
affects: All versions
Errors
Common errors & fixes
reversion.errors.RegistrationError: class 'myapp.MyModel' has already been registered with Reversion
This error occurs when a Django model is registered with `django-reversion` more than once, typically due to relative import statements causing the `models.py` file to be imported multiple times.
fix
Convert all relative imports in your codebase to absolute imports to ensure models are registered only once. For example, instead of `from .models import MyModel`, use `from myapp.models import MyModel`.
reversion.errors.RevertError: Could not load <Foo: bar> - incompatible version data
This error happens when the schema of a model changes (e.g., a field is removed) after versions have been stored. `django-reversion` stores versions as JSON, and older JSON data may no longer be compatible with the current model definition during a revert attempt.
fix
If a field was removed, older versions containing that field's data cannot be deserialized. The recommended approach is to either delete the incompatible versions or manually adjust the serialized data if possible, though deleting is more common for problematic older revisions. Schema migrations that add new fields generally do not cause this issue.
TypeError: Model instances without primary key value are unhashable
This error typically arises when `django-reversion` attempts to process a model instance (often a related object within a revision context) that does not yet have a primary key, such as a newly created but unsaved object, or an object that had its primary key removed during a deletion process, making it unhashable in sets used internally by reversion.
fix
Ensure that any model instances being tracked or processed within a reversion context (especially related objects) have been saved to the database and thus have a primary key before the reversion context attempts to hash or retrieve them. This can sometimes occur during complex save/delete operations involving related models within a single transaction.
django.core.exceptions.ImproperlyConfigured: Cannot use VersionAdmin with a database that does not support savepoints.
The `VersionAdmin` class in `django-reversion` requires the underlying database to support savepoints for transaction management, which is essential for its rollback and recovery features. This error occurs if the configured database backend does not support them.
fix
Ensure you are using a database backend that supports savepoints (e.g., PostgreSQL, SQLite, MySQL with InnoDB). If you are using a non-supporting database, you will need to switch to one that does or avoid using `VersionAdmin` functionality.
django.db.utils.IntegrityError: NOT NULL constraint failed: myapp_mymodel.new_field_id
This `IntegrityError` (or similar foreign key constraint errors) often occurs when attempting to revert to an older version of a model after a schema migration has added new fields with `NOT NULL` constraints without a default value, or when foreign key relationships cannot be satisfied by the old version's data.
fix
When reverting after schema changes, especially those adding non-nullable fields, you might need to manually ensure that the reverted data conforms to the current schema. This often means providing default values for new non-nullable fields in the old version's data or handling the migration carefully by clearing revision data or using `createinitialrevisions` after migrations.
Upgrade
Version history
6.3.0latest on PyPI · released Jun 12, 2026
Audit
Dependencies
DjangorequiredCore framework dependency, requires Django 4.2 or later.
PythonrequiredRequires Python 3.9 or later.
Agent activity
21 hits · last 30 days
node
18
OpenAI (training)
1
Resources
django-reversion — pip install django-reversion · libregistry