NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #2686 most downloaded on PyPI
An extension to the Django web framework that provides version control for model instances.
Last release 3 months ago
12 Jun 2026
Release timing varies
gaps range from 9 days to 1.1 years
Most releases are documented
notes for 44 of the last 60 stable releases
1 version withdrawn
withdrawn after publishing
15 years old
88 releases · first in 2012
feat: add Turkish translation for django-reversion by @mcihad in #1000
Add explicit Django versions to classifiers by @Michael-Deveau in #995
One column per quarter.
Full Changelog: v6.1.0...v6.2.0
Added object_id_field to reversion.register() (@philippeducasse).
Implement date-based ordering and custom version sort by @micmarc in #992
Added history_order_by_date and get_version_ordering to VersionAdmin (@micmarc).
Fixing doc build by @etianen in #989
Full Changelog: v5.1.0...v6.0.0
Prevent Django signals firing when viewing historical versions in admin. Django model signals (pre_save, post_save, pre_delete, post_delete, m2m_changed) are now muted during GET requests to revision views, preventing unintended side effects from signal handlers when users view historical data. (@romanek-adam-b2c2)
Switch call from removed is_hidden method to hidden property by @jeremy-engel in #969
Full Changelog: v5.0.12...v5.1.0
Django 5 support (@jeremy-engel).
Use bulk_create on supported databases (@stianjensen).
Add missing migration by @pinguin999 in #960
Full Changelog: v5.0.11...v5.0.12
Improved the Chinese translation by @zengqiu in #956
Fix N+1 queries while rendering the recover_list.html template (@armonge).
Fix N+1 queries while rendering the recover_list.html template (@armonge).
- Broken release.
Broken release.
Fix get_deleted (@siddarta-weis, @etianen).
Fix get_deleted (@siddarta-weis, @etianen).
Speed up get_deleted (@caullla).
Speed up get_deleted (@caullla).
Fix handling case of missing object in admin revert (@julianklotz)
Fix handling case of missing object in admin revert (@julianklotz)
Handling case of missing object in admin revert (@etianen, @PavelPancocha)
Handling case of missing object in admin revert (@etianen, @PavelPancocha)
CI improvements (@etianen, @browniebroke)
Fix warning log formatting for failed reverts (@tony).
Fix warning log formatting for failed reverts (@tony).
A revision will no longer be created if a transaction is marked as rollback, as this would otherwise cause an additional database error (@proofit404).
A revision will no longer be created if a transaction is marked as rollback, as this would otherwise cause an additional database error (@proofit404).
A warning log is now emitted if a revert fails due to database integrity errors, making debugging the final RevertError easier.
Fixed doc builds on readthedocs (@etianen).
Fixed doc builds on readthedocs (@etianen).
Fix admin detail view in multi-database configuration (@atten).
Fix admin detail view in multi-database configuration (@atten).
Added support for using django-reversion contexts in asyncio tasks (@bellini666).
Added support for using django-reversion contexts in asyncio tasks (@bellini666).
Breaking: Dropped support for Python 3.6.
Improved performance of createinitialrevisions management command (@philipstarkey).
Improved performance of createinitialrevisions management command (@philipstarkey).
Django 4.0b support (@smithdc1, @kevinmarsh).
Django 4.0b support (@smithdc1, @kevinmarsh).
Optimized VersionQuerySet.get_deleted.
Deprecation removals (@lociii, @Peter-van-Tol).
Breaking: The create_revision view decorator and RevisionMiddleware no longer roll back the revision and database transaction on response status code >= 400. It's the responsibility of the view to use transaction.atomic() to roll back any invalid data. This can be enabled globally by setting ATOMIC_REQUESTS=True. (@etianen)
https://docs.djangoproject.com/en/3.1/ref/settings/#std:setting-DATABASE-ATOMIC_REQUESTS
Fixing gettext plural forms with Django (@martinsvoboda).
Deprecation removals (@lociii, @Peter-van-Tol).
CI testing improvements (@etianen, @michael-k).
Documentation fixes (@erikrw, @jedie, @michael-k).
Significant speedup to Version.objects.get_deleted(...) database query for PostgreSQL (@GeyseR).
Significant speedup to Version.objects.get_deleted(...) database query for PostgreSQL (@GeyseR).
Testing against Django 3.1 (@michael-k).
Django 4.0 compatibility improvements (@GitRon).
Added use_natural_foreign_keys option to reversion.register() (@matwey).
Added use_natural_foreign_keys option to reversion.register() (@matwey).
Documentation improvments and minor fixes (@ad-m, @martey, @annainfo, @etianen, @m4rk3r, @adityakrgupta25, @ekinertac).
Dropped support for Django 1.11 LTS.
Removing deprecated usages of ugettext_lazy (@François GUÉRIN).
Removing deprecated usages of ugettext_lazy (@François GUÉRIN).
Slovenian translation (@Bor Plestenjak).
Removing deprecated usages of force_text (@Tenzer).
Packaging improvements (@michael-k).
Removing deprecated usages of force_text (@Tenzer).
Documentation fixes (@chicheng).
Improved performance of get_deleted for large datasets (@jeremy-engel).
Improved performance of get_deleted for large datasets (@jeremy-engel).
Django 3.0 compatibility (@claudep).
Drops Django < 1.11 compatibility (@claudep).
Drops Python 2.7 compatibility (@claudep).
Fixed errors in management commands when django.contrib.admin is not in INSTALLED_APPS (@irtimir).
Remove django.contrib.admin dependency from django-reversion (Aitor Ruano).
Remove django.contrib.admin dependency from django-reversion (Aitor Ruano).
README refactor (@rhenter).
Testing against Django 2.2 (@claudep).
Improved performance of many reversion database queries using EXISTS subquery (@MRigal).
Improved performance of many reversion database queries using EXISTS subquery (@MRigal).
Added support for Django 2.1 view permission (@ofw).
Removed squashed migrations, as they subtly messed up the Django migrations framework (@etianen).
Removed squashed migrations, as they subtly messed up the Django migrations framework (@etianen).
To upgrade to >= 3.0.2 from < 3.0.1:
pip install django-reversion==3.0.1
python manage.py migrate reversion
pip install --upgrade django-reversion
python manage.py migrate reversion
Added squashed migrations back in to allow older installations to upgrade (Christopher Thorne).
Added squashed migrations back in to allow older installations to upgrade (Christopher Thorne).
Fixed TypeError exception when accessing m2m_data attribute from a field that points to Django’s User model (@denisroldan).
Breaking: Revision.comment now contains the raw JSON change message generated by django admin, rather than a string. Accessing Revision.comment direct
Breaking: Revision.comment now contains the raw JSON change message generated by django admin, rather than a string. Accessing Revision.comment directly is no longer recommended. Instead, use Revision.get_comment(). (@RamezIssac).
BREAKING: django-reversion now uses _base_manager to calculate deleted models, not _default_manager. This change will only affect models that perform default filtering in their _default_manager (@ivissani).
Added request_creates_revision hook to RevisionMiddleware and views.create_revision. (@kklingenberg).
Added revision_request_creates_revision hook to views.RevisionMixinView. (@kklingenberg).
Added --meta flag to ./manage.py createrevisions (@massover).
Fixed bug when reverting deleted nested inlines (Primož Kariž).
Added tests for django 2.1 (@claudep).
Improve performance of get_deleted() for Oracle (@passuf).
Improve performance of get_deleted() for Oracle (@passuf).
Minor tweaks (@etianen, @michael-k).
Fixed MySQL error in get_deleted().
Fixed MySQL error in get_deleted().
Dramatically improved performance of get_deleted() over large datasets (@alexey-v-paramonov, @etianen).
Dramatically improved performance of get_deleted() over large datasets (@alexey-v-paramonov, @etianen).
Ukranian translation (@illia-v).
Bugfixes (@achidlow, @claudep, @etianen).
Bugfix: Handling case of None user in request (@pawelad).
Bugfix: Handling case of None user in request (@pawelad).
Documentation corrections (@danielquinn).
Bugfix: "invalid literal for int() with base 10: 'None'" for unversioned admin inline relations.
If, after updating, you still experience this issue, run the following in a Django shell:
from reversion.models import Version
Version.objects.filter(object_id="None").delete()
Important: Ensure that none of your versioned models contain a string primary key where "None" is a valid value before running this snippet!
Bugfix: Deleted inline admin instances no longer added to revision.
Bugfix: Deleted inline admin instances no longer added to revision.
Bugfix: M2M relations correctly added to revision (@etianen, @claudep).
Improved performance of 0003 migration (@mkurek).
Documentation improvements (@orlra, @guettli, @meilinger).
Django 1.11 support (@claudep).
Added atomic=True parameter to create_revision (Ernesto Ferro).
Setting revision.user in process_response for middleware (@etianen).
Setting revision.user in process_response for middleware (@etianen).
Fixing localization of model primary keys in recover_list.html (@w4rri0r3k).
Documentation tweaks (@jaywink).
Deprecation fixes (@KhasanovBI, @zsiciarz, @claudep).
Database migrations now db-aware (@alukach).
Added "revert" and "recover" context variables to admin templates (@kezabelle).
Added post_revision_commit and pre_revision_commit signals back in (@carlosxl).
Fixing datetime in admin change message (@arogachev).
Fixing performance bug in postgres (@st4lk).
Fixing admin change messages in Django 1.10+ (@claudep).
Fixing revision middleware behavior in Django 1.10+ (@etianen).
Documentation tweaks (@jschneier).
Deprecation fixes (@KhasanovBI, @zsiciarz, @claudep).
Releasing as a universal wheel (@adamchainz).
Fixed RevisionMiddleware always rolling back transactions in gunicorn (@stebunovd, @etianen).
Fixed RevisionMiddleware always rolling back transactions in gunicorn (@stebunovd, @etianen).
Tweaks and minor bugfixes (@SahilMak).
Fixed LookupError when running migration 0003 with stale content types (@etianen).
Fixed LookupError when running migration 0003 with stale content types (@etianen).
Fixed LookupError when running migration 0003 (@etianen).
Fixed LookupError when running migration 0003 (@etianen).
Fixed duplicate versions using get_deleted() (@etianen).
Fixed unexpected deletion of underflowing revisions when using --keep switch with deleterevisions (@etianen).
Added support for m2m fields with a custom through model (@etianen).
Added support for m2m fields with a custom through model (@etianen).
Fixing migration 0003 in MySQL (@etianen).
Fixing migration 0003 in MySQL (@etianen).
Improved performance of migration 0003 (@BertrandBordage).
Improved performance of migration 0003 (@BertrandBordage).
De-duplicating Version table before applying migration 0004 (@BertrandBordage, @etianen).
django-reversion was first released in May 2008, and has been in active development ever since. Over this time it's developed a certain amount of cruf
django-reversion was first released in May 2008, and has been in active development ever since. Over this time it's developed a certain amount of cruft from legacy and unused features, resulting in needless complexity and multiple ways of achieving the same task.
This release substantially cleans and refactors the codebase. Much of the top-level functionality remains unchanged or is very similar. The release notes are divided into subsections to make it easier to find out where you need to update your code.
This release includes a migration for the Version model that may take some time to complete.
Dramatically improved performance of version lookup for models with a non-integer primary key (@etianen, @mshannon1123).
Documentation refactor (@etianen).
Test refactor (@etianen).
Minor tweaks and bugfixes (@etianen, @bmarika, @ticosax).
Fixed issue with empty revisions being created in combination with RevisionMiddleware (@etianen).
Breaking: Removed reversion_format property from VersionAdmin (@etianen).
Use VersionAdmin.reversion_register instead.
class YourVersionAdmin(VersionAdmin): def reversion_register(self, model, **options): options["format"] = "yaml" super(YourVersionAdmin, self).reversion_register(model, **options)
Breaking: Removed ignore_duplicate_revisions property from VersionAdmin (@etianen).
Use VersionAdmin.reversion_register instead.
class YourVersionAdmin(VersionAdmin): def reversion_register(self, model, **options): options["ignore_duplicates"] = True super(YourVersionAdmin, self).reversion_register(model, **options)
Breaking: Refactored arguments to createinitialrevisions (@etianen).
All existing functionality should still be supported, but several parameter names have been updated to match Django coding conventions.
Check the command --help for details.
Breaking: Refactored arguments to deleterevisions (@etianen).
All existing functionality should still be supported, but several parameter names have been updated to match Django coding conventions, and some duplicate parameters have been removed. The confirmation prompt has been removed entirely, and the command now always runs in the --force mode from the previous version.
Check the command --help for details.
Added support for using RevisionMiddleware with new-style Django 1.10 MIDDLEWARE (@etianen).
Middleware wraps entire request in transaction.atomic() to preserve transactional integrity of revision and models (@etianen).
Added reversion.views.create_revision view decorator (@etianen).
Added reversion.views.RevisionMixin class-based view mixin (@etianen).
Restored many of the django-reversion API methods back to the top-level namespace (@etianen).
Revision blocks are now automatically wrapped in transaction.atomic() (@etianen).
Added for_concrete_model argument to reversion.register() (@etianen).
Added Version.objects.get_for_model() lookup function (@etianen).
Added reversion.add_to_revision() for manually adding model instances to an active revision (@etianen).
Removed Version.object_id_int field, in favor of a unified Version.object_id field for all primary key types (@etianen).
Breaking: reversion.get_for_object_reference() has been moved to Version.objects.get_for_object_reference() (@etianen).
Breaking: reversion.get_for_object() has been moved to Version.objects.get_for_object() (@etianen).
Breaking: reversion.get_deleted() has been moved to Version.objects.get_deleted() (@etianen).
Breaking: Version.object_version has been renamed to Version._object_version (@etianen).
Breaking: Refactored multi-db support (@etianen).
django-reversion now supports restoring model instances to their original database automatically. Several parameter names have also be updated to match Django coding conventions.
If you made use of the previous multi-db functionality, check the latest docs for details. Otherwise, everything should just work.
Breaking: Removed get_ignore_duplicates and set_ignore_duplicates (@etianen).
ignore_duplicates is now set in reversion.register() on a per-model basis.
Breaking: Removed get_for_date() function (@etianen).
Use get_for_object().filter(revision__date_created__lte=date) instead.
Breaking: Removed get_unique_for_object() function (@etianen).
Use get_for_object().get_unique() instead.
Breaking: Removed signal and eager_signals argument from reversion.register() (@etianen).
To create revisions on signals other than post_save and m2m_changed, call reversion.add_to_revision() in a signal handler for the appropriate signal.
from django.dispatch import receiver import reversion from your_app import your_custom_signal @reciever(your_custom_signal) def your_custom_signal_handler(instance, **kwargs): if reversion.is_active(): reversion.add_to_revision(instance)This approach will work for both eager and non-eager signals.
Breaking: Removed adapter_cls argument from reversion.register() (@etianen).
Breaking: Removed reversion.save_revision() (@etianen).
Use reversion.add_to_revision() instead.
import reversion with reversion.create_revision(): reversion.add_to_revision(your_obj)
Breaking: Removed pre_revision_commit signal (@etianen).
Use the Django standard pre_save signal for Revision instead.
Breaking: Removed post_revision_commit signal (@etianen).
Use the Django standard post_save signal for Revision instead.
Breaking: Removed patch_admin function (@etianen).
Use VersionAdmin as a mixin to 3rd party ModelAdmins instead.
@admin.register(SomeModel) class YourModelAdmin(VersionAdmin, SomeModelAdmin): pass
Breaking: Removed generate_diffs function (@etianen).
django-reversion no supports an official diff helper. There are much better ways of achieving this now, such as django-reversion-compare.
The old implementation is available for reference from the previous release.
Breaking: Removed generate_patch function (@etianen).
django-reversion no supports an official diff helper. There are much better ways of achieving this now, such as django-reversion-compare.
The old implementation is available for reference from the previous release.
Breaking: Removed generate_patch_html function (@etianen).
django-reversion no supports an official diff helper. There are much better ways of achieving this now, such as django-reversion-compare.
The old implementation is available for reference from the previous release.
Breaking: Ordering of -pk added to models Revision and Version. Previous was the default pk.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →