NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #1802 most downloaded on PyPI
Store model history and view/revert changes from admin site.
Last release 2 months ago
22 Jul 2026
Ships fairly regularly
a new release about every 5 months
Nearly every release is documented
notes for 51 of 53 stable releases
Nothing withdrawn
no release was ever pulled
13 years old
54 releases · first in 2013
Fix HistoricForeignKey reverse prefetch_related (rebases #1159 and addresses review) by @tomhampshire in #1604
Full Changelog: 3.12.0...3.13.0
One column per quarter.
Breaking changes:
Dropped support for Django 4.2, which reached end-of-life on 2026-04-07 (gh-1630)
Dropped support for Django 5.0, which reached end-of-life on 2025-04-02 (gh-1630)
Dropped support for Django 5.1, which reached end-of-life on 2025-12-03 (gh-1630)
Bug fixes:
Fixed the behavior of HistoricForeignKey when used together with prefetch_related(), which caused some related objects to be missing (gh-1152)
The project is going into a "keep the lights on" maintenance mode for now. That means the two current maintainers are still dedicated toward doing wor
The project is going into a "keep the lights on" maintenance mode for now.
That means the two current maintainers are still dedicated toward doing work that's vitally important for the project itself, but they can unfortunately not provide timely responses to most other issues or PRs - even though it might sporadically happen.
Please voice any concerns in the dedicated issue, which also contains more details on the project's status.
.readthedocs.yaml by @ddabble in #1613Full Changelog: 3.11.0...3.12.0
Add Python 3.14 and Django 6.0 to CI workflow matrix by @cclauss in #1529
Full Changelog: 3.10.1...3.11.0
<!-- Release notes generated using configuration in .github/release.yml at master -->
Full Changelog: https://github.com/django-commons/django-simple-history/compare/3.10.1...3.11.0
New features:
Added support for Python 3.14 (gh-1529)
Added support for Django 6.0 (gh-1529)
Added Ukrainian localization (gh-1547)
Breaking changes:
Dropped support for Python 3.9, which reached end-of-life on 2025-10-31 (gh-1560)
Fixed changed log syntax to support PyPI packaging. by @tim-schilling in #1499
Full Changelog: 3.10.0...3.10.1
<!-- Release notes generated using configuration in .github/release.yml at 3.10.1 -->
Full Changelog: https://github.com/django-commons/django-simple-history/compare/3.10.0...3.10.1
Development:
Fixed changelog syntax to support PyPI packaging (gh-1499)
Make skip_history_when_saving work when creating a new object by @ddabble in #1262
skip_history_when_saving work when creating a new object by @ddabble in #1262Full Changelog: 3.7.0...3.8.0
<!-- Release notes generated using configuration in .github/release.yml at master -->
skip_history_when_saving work when creating a new object by @ddabble in https://github.com/jazzband/django-simple-history/pull/1262Full Changelog: https://github.com/jazzband/django-simple-history/compare/3.7.0...3.8.0
New features:
Made skip_history_when_saving work when creating an object - not just when updating an object (gh-1262)
Added HistoricOneToOneField (gh-1394)
Added support for Django 5.1 (gh-1388)
Added pagination to SimpleHistoryAdmin (gh-1277)
Added support for Django 5.2 (gh-1441)
Breaking changes:
Dropped support for Python 3.8, which reached end-of-life on 2024-10-07 (gh-1421)
Deprecations:
simple_history_admin_list.display_list() was planned to be removed in this release, but it was overlooked, and will instead be removed in 3.9.0
Bug fixes:
Fixed issue with deferred fields causing DoesNotExist error (gh-678)
Fixed issue with history button not working when viewing historical entries in the admin (gh-527)
Other changes:
Improved performance of the latest_of_each() history manager method (gh-1360)
Updated all djangoproject.com links to reference the stable version (gh-1420)
Drop support for Django 3.2 by @ddabble in #1344
Full Changelog: 3.6.0...3.7.0
<!-- Release notes generated using configuration in .github/release.yml at master -->
Full Changelog: https://github.com/jazzband/django-simple-history/compare/3.6.0...3.7.0
Breaking changes:
Dropped support for Django 3.2, which reached end-of-life on 2024-04-01 (gh-1344)
Removed the temporary requirement on asgiref>=3.6 added in 3.5.0, now that the minimum required Django version is 4.2 (gh-1344)
Migrated package building from using the deprecated setup.py to using pyproject.toml (with Hatchling as build backend); setup.py has consequently been removed (gh-1348)
Added django>=4.2 as an installation dependency, to mirror the minimum version tested in our CI (gh-1349)
Support customizing the history manager and historical queryset classes by @tim-schilling in #1306
Full Changelog: 3.5.0...3.6.0
<!-- Release notes generated using configuration in .github/release.yml at master -->
Full Changelog: https://github.com/jazzband/django-simple-history/compare/3.5.0...3.6.0
New features:
Support custom History Manager and QuerySet classes (gh-1280)
Added SimpleHistoryAdmin.get_history_queryset() for overriding which QuerySet is used to list the historical records (gh-1128)
Added SimpleHistoryAdmin.get_history_list_display() which returns history_list_display by default, and made the latter into an actual field (gh-1128)
diff_against() has a new keyword argument, foreign_keys_are_objs; see usage in the docs under "History Diffing" (gh-1128)
Added a "Changes" column to SimpleHistoryAdmin's object history table, listing the changes between each historical record of the object; see the docs under "Customizing the History Admin Templates" for overriding its template context (gh-1128)
Breaking changes:
Renamed the (previously internal) admin template simple_history/_object_history_list.html to simple_history/object_history_list.html, and added the field SimpleHistoryAdmin.object_history_list_template for overriding it (gh-1128)
ModelDelta and ModelChange (in simple_history.models) are now immutable dataclasses; their signatures remain unchanged (gh-1128)
ModelDelta's changes and changed_fields are now sorted alphabetically by field name. Also, if ModelChange is for an M2M field, its old and new lists are sorted by the related object. This should help prevent flaky tests. (gh-1128)
Deprecations:
Deprecated the undocumented template tag simple_history_admin_list.display_list(); it will be removed in version 3.8 (gh-1128)
Bug fixes:
Fixed the setting SIMPLE_HISTORY_ENABLED = False not preventing M2M historical records from being created (gh-1328)
Other changes:
For history-tracked M2M fields, adding M2M objects (using add() or set()) used to cause a number of database queries that scaled linearly with the number of objects; this has been fixed to now be a constant number of queries (gh-1333)
Exclude bots from generated release notes by @hugovk in #1231
asgiref requirement by @ddabble in #1261Full Changelog: 3.4.0...3.5.0
<!-- Release notes generated using configuration in .github/release.yml at master -->
asgiref requirement by @ddabble in https://github.com/jazzband/django-simple-history/pull/1261Full Changelog: https://github.com/jazzband/django-simple-history/compare/3.4.0...3.5.0
New features:
Allow HistoricalRecords.m2m_fields as str (gh-1243)
Added custom_historical_attrs to bulk_create_with_history() and bulk_update_with_history() for setting additional fields on custom history models (gh-1248)
Passing an empty list as the fields argument to bulk_update_with_history() is now allowed; history records will still be created (gh-1248)
Support Simplified Chinese translation (gh-1281)
Added support for Django 5.0 (gh-1283)
Added support for Python 3.13 (gh-1289)
Breaking changes:
Added temporary requirement on asgiref>=3.6 while the minimum required Django version is lower than 4.2 (gh-1261)
Bug fixes:
Fixed FieldError when creating historical records for many-to-many fields with to="self" (gh-1218)
Fixed HistoryRequestMiddleware deleting non-existent HistoricalRecords.context.request in very specific circumstances (gh-1256)
Other changes:
Small performance optimization of the clean-duplicate_history command (gh-1015)
Fix failing admin tests when testing against Django's main branch by @ddabble in https://github.com/jazzband/django-simple-history/pull/1140
Full Changelog: https://github.com/jazzband/django-simple-history/compare/3.3.0...3.4.0
New features:
Added feature to evaluate history model permissions explicitly when SIMPLE_HISTORY_ENFORCE_HISTORY_MODEL_PERMISSIONS is set to True in settings (gh-1017).
Support Indonesian translation (gh-1198)
Support Urdu translation (gh-1199)
Support Norwegian Bokmål translation (gh-1210)
Added support for Django 4.2 (gh-1202)
Made bulk_update_with_history() return the number of model rows updated (gh-1206)
Made HistoryRequestMiddleware async-capable (gh-1209)
Breaking changes:
Dropped support for Python 3.7, which reached end-of-life on 2023-06-27 (gh-1202)
Dropped support for Django 4.0, which reached end-of-life on 2023-04-01 (gh-1202)
Bug fixes:
Fixed SimpleHistoryAdmin not properly integrating with custom user models (gh-1177)
Fixed HistoryRequestMiddleware not cleaning up after itself (i.e. deleting HistoricalRecords.context.request) under some circumstances (gh-1188)
Fixed error when setting table_name with inherit=True (gh-1195)
Other changes:
Fixed typos in the docs
M2M support for inheritance and signals by @legau in https://github.com/jazzband/django-simple-history/pull/1042
KeyError when cleaning duplicate history by @ddabble in https://github.com/jazzband/django-simple-history/pull/1038Full Changelog: https://github.com/jazzband/django-simple-history/compare/3.2.0...3.3.0
New features:
Made it possible to use the new m2m_fields with model inheritance (gh-1042)
Added two signals: pre_create_historical_m2m_records and post_create_historical_m2m_records (gh-1042)
Added tracked_fields attribute to historical models (gh-1038)
Added support for Python 3.11 (gh-1053)
Added Arabic translations (gh-1056)
Added a --base-manager option to the clean_duplicate_history management command (gh-1115)
Bug fixes:
Fixed KeyError when running clean_duplicate_history on models with excluded_fields (gh-1038)
Other changes:
Fixed a code example under "Tracking many to many relationships" (gh-1069)
Replaces count by exists in populate_history command by @fabiocapsouza in https://github.com/jazzband/django-simple-history/pull/982
Full Changelog: https://github.com/jazzband/django-simple-history/compare/3.1.1...3.2.0
New features:
Add basic support for many-to-many fields (gh-399)
Added support for Django 4.1 (gh-1021)
Other changes:
Fixed typos in the docs
Removed n+1 query from bulk_create_with_history utility (gh-975)
Started using exists query instead of count in populate_history command (gh-982)
Fix stale py36 references in pyproject.toml by @jeking3 in https://github.com/jazzband/django-simple-history/pull/978
Full Changelog: https://github.com/jazzband/django-simple-history/compare/3.1.0...3.1.1
Other changes:
Fix py36 references in pyproject.toml (gh-960)
Fix local setup.py install versioning issue (gh-960)
Remove py2 universal wheel cfg - only py3 needed now (gh-960)
Dropped support for Django 2.2 (gh-968)
makemigrations after upgrading to realize the benefit of indexing changes.as_of (gh-397)history_date column; opt-out with setting SIMPLE_HISTORY_DATE_INDEX (gh-565)no_db_index setting, to drop indices in historical models,
default stays the same (gh-720)included_fields for history.diff_against (gh-776)history.diff_against by reducing number of queries to 0 in most cases (gh-776)prev_record and next_record performance when using excluded_fields (gh-791)update_change_reason in pk (gh-806)OrderingFilter (gh-821)make format so it works by using tox (gh-859)history_date records (gh-861)excluded_field_kwargs to support custom OneToOneField that have
additional arguments that don't exist on ForeignKey. (gh-870)history.diff_against with non-editable fields (gh-923)get_change_reason_for_object method after subclassing HistoricalRecords (gh-962)New features:
Added queryset-based filtering with as_of (gh-397)
Added index on history_date column; opt-out with setting SIMPLE_HISTORY_DATE_INDEX (gh-565)
RecordModels now support a no_db_index setting, to drop indices in historical models, default stays the same (gh-720)
Support included_fields for history.diff_against (gh-776)
Added excluded_field_kwargs to support custom OneToOneField that have additional arguments that don't exist on ForeignKey. (gh-870)
Added Czech translations (gh-885)
Russian translations update (gh-897)
Added support for Django 4.0 (gh-898)
Added Python 3.10 to test matrix (gh-899)
Added HistoricForeignKey (gh-940)
Support change reason formula feature. Change reason formula can be defined by overriding get_change_reason_for_object method after subclassing HistoricalRecords (gh-962)
Breaking changes:
Dropped support for Django 2.2 (gh-968)
Dropped support for Django 3.1 (gh-952)
Dropped support for Python 3.6, which reached end-of-life on 2021-12-23 (gh-946)
Upgrade instructions:
Run makemigrations after upgrading to realize the benefit of indexing changes.
Bug fixes:
Fixed update_change_reason in pk (gh-806)
Fixed bug where serializer of djangorestframework crashed if used with OrderingFilter (gh-821)
Fixed bug where latest() is not idempotent for identical history_date records (gh-861)
Fix bug with history.diff_against with non-editable fields (gh-923)
Other changes:
Improve performance of history.diff_against by reducing number of queries to 0 in most cases (gh-776)
Fixed prev_record and next_record performance when using excluded_fields (gh-791)
Development:
Fixed make format so it works by using tox (gh-859)
Added ability to break into debugger on unit test failure (gh-890)
Added pre-commit for better commit quality (gh-896)
Removed changeReason in favor of _change_reason (see 2.10.0)
Breaking changes:
changeReason in favor of _change_reason (see 2.10.0)Full list of changes:
ignore_conflicts in bulk_create_with_history (gh-733)asgiref when available instead of thread locals (gh-747)history.as_of speed improvements by calculating in the DB (gh-758)black and isort python version to 3.6 (gh-817)New features:
Add Python 3.9 support (gh-745)
Add Django 3.2 support (gh-817)
Support ignore_conflicts in bulk_create_with_history (gh-733)
Improve French translations (gh-811)
Breaking changes:
Removed support for Django versions prior to 2.2 (gh-652)
Removed support for Django 3.0 (gh-817)
Removed changeReason in favor of _change_reason - see 2.10.0 (gh-819)
Other changes:
Use asgiref when available instead of thread locals (gh-747)
Queryset history.as_of speed improvements by calculating in the DB (gh-758)
Development:
Migrate from TravisCI to Github Actions (gh-739)
Sort imports with isort (gh-751)
Increase black and isort python version to 3.6 (gh-817)
Add default date to bulk_create_with_history and bulk_update_with_history (gh-687)
bulk_create_with_history and bulk_update_with_history (gh-687)bulk_create_with_history (gh-699)--excluded_fields argument to clean_duplicate_history command (gh-674)bulk_create_with_history and
bulk_update_with_history instead of objects (gh-703)manager argument to bulk_update_with_history to use instead of
the default manager (gh-703)clean_old_history command's --days argument (gh-722)* NOTE: This will be the last minor release before 3.0.0.
Added clean_old_history management command (gh-675)
clean_old_history management command (gh-675)user_db_constraint param to history to avoid circular reference on delete (gh-676)get_user from HistoricalRecords in order to set a fallback user on
bulk update and bulk create (gh-677)Start using _change_reason instead of changeReason to add change reasons to historical objects. changeReason is deprecated and will be removed in vers…
bulk_update_with_history utility function (gh-650)bulk_create_with_history and bulk_update_with_history (gh-653)_change_reason instead of changeReason to add change reasons to historical
objects. changeReason is deprecated and will be removed in version 3.0.0 (gh-655)Add simple filtering if provided a minutes argument in clean_duplicate_history (gh-606)
clean_duplicate_history (gh-606)FileField to CharField instead of TextField (gh-625)ContentType in SimpleHistoryAdmin using django_apps.get_model
to avoid possible AppRegistryNotReady exception (gh-630)utils.update_change_reason when user specifies excluded_fields (gh-637)now is imported from timezone (timezone module is imported now) (gh-643)Fixed bulk_create_with_history support for HistoryRecords with relation_name attribute (gh-591)
bulk_create_with_history support for HistoryRecords with relation_name attribute (gh-591)bulk_create_with_history for databases different from PostgreSQL (gh-577)DoesNotExist error when trying to get instance if object is deleted (gh-571)model_to_dict to detect changes in a parent model when using
inherit=True (backwards-incompatible for users who were directly
using previous version) (gh-576)clean_duplicate_history (gh-604)Fixed BigAutoField not mirrored as BigInt (gh-556)
Fixed ModuleNotFound issue for six (gh-553)
Replace deprecated django.utils.six with six (gh-526)
django.utils.six with six (gh-526)custom_model_name parameter to be a callable (gh-489)\* Add support for using chained manager method and save/delete keyword argument (gh-507)
using chained manager method and save/delete keyword argument (gh-507)clean_duplicate_history to remove duplicate history entries (gh-483)'self' (gh-513)history_user_id_field (gh-511)* NOTE: This change was not backward compatible for users using routers to write history tables to a separate database from their base tables. This issue is fixed in 2.7.1.
Add app parameter to the constructor of HistoricalRecords (gh-486)
app parameter to the constructor of HistoricalRecords (gh-486)custom_model_name parameter to the constructor of HistoricalRecords (gh-451)pre_create_historircal_record to pass history_instance for ease of customization (gh-421)extra_context parameter to history_form_view (gh-467)next_record and prev_record to work with custom manager names (gh-501)Add '+' as the history_type for each instance in bulk_history_create (gh-449)
Add ability to cascade delete historical records when master record is deleted (gh-440)
Add pre and post create_historical_record signals (gh-426)
Add ability to diff HistoricalRecords (gh-244)
Add ability to specify alternative user_model for tracking (gh-371)
bulk_create_with_history to allow bulk_create with history saved (gh-412)Fixed out-of-memory exception when running populate_history management command (gh-408)
Add ability to specify custom history_reason field (gh-379)
prev_record and next_record (gh-365)Added Django 2.0 support (gh-330)
Use get_queryset rather than model.objects in history_view. (gh-303)
Nothing published for this version
Add –batchsize option to the populate_history management command. (gh-231)
- Add Polish locale. - Add Django 1.10 support.
Add Polish locale.
Add Django 1.10 support.
Clear the threadlocal request object when processing the response to prevent test interactions. (gh-213)
Clear the threadlocal request object when processing the response to prevent test interactions. (gh-213)
History tracking can be inherited by passing inherit=True. (gh-63)
History tracking can be inherited by passing inherit=True. (gh-63)
Add ability to list history in admin when the object instance is deleted. (gh-72)
Add ability to list history in admin when the object instance is deleted. (gh-72)
Add ability to change history through the admin. (Enabled with the SIMPLE_HISTORY_EDIT setting.)
Add Django 1.9 support.
Support for custom tables names. (gh-196)
Respect to_field and db_column parameters (gh-182)
Respect to_field and db_column parameters (gh-182)
Use app loading system and fix deprecation warnings on Django 1.8 (gh-172)
Use app loading system and fix deprecation warnings on Django 1.8 (gh-172)
Update Landscape configuration
Fix OneToOneField transformation for historical models (gh-166)
Fix OneToOneField transformation for historical models (gh-166)
Disable cascading deletes from related models to historical models
Fix restoring historical instances with missing one-to-one relations (gh-162)
Deprecated use of CustomForeignKeyField (to be removed)
Add support for Django 1.8+
Deprecated use of CustomForeignKeyField (to be removed)
Remove default reverse accessor to auth.User for historical models (gh-121)
Fix a bug when models have a ForeignKey with primary_key=True
Fix a bug when models have a ForeignKey with primary_key=True
Do NOT delete the history elements when a user is deleted.
Add support for latest
Allow setting a reason for change. [using option changeReason]
Fix migrations while using order_with_respsect_to (gh-140)
Fix migrations while using order_with_respsect_to (gh-140)
Fix migrations using south
Allow history accessor class to be overridden in register()
Additional fix for migrations (gh-128)
Additional fix for migrations (gh-128)
Removed some incompatibilities with non-default admin sites (gh-92)
Removed some incompatibilities with non-default admin sites (gh-92)
Fixed error caused by HistoryRequestMiddleware during anonymous requests (gh-115 fixes gh-114)
Added workaround for clashing related historical accessors on User (gh-121)
Added support for MongoDB AutoField (gh-125)
Fixed CustomForeignKeyField errors with 1.7 migrations (gh-126 fixes gh-124)
Extended availability of the as_of method to models as well as instances.
Extended availability of the as_of method to models as well as instances.
Allow history_user on historical objects to be set by middleware.
Fixed error that occurs when a foreign key is designated using just the name of the model.
Drop Django 1.3 support
Fixed error that occurs when models have a foreign key pointing to a one to one field.
Fixed error that occurs when models have a foreign key pointing to a one to one field.
Fix bug when model verbose_name uses unicode (gh-76)
Allow non-integer foreign keys
Allow foreign keys referencing the name of the model as a string
Added the ability to specify a custom history_date
Note that simple_history should be added to INSTALLED_APPS (gh-94 fixes gh-69)
Properly handle primary key escaping in admin URLs (gh-96 fixes gh-81)
Add support for new app loading (Django 1.7+)
Allow specifying custom base classes for historical models (gh-98)
Fixed bug when using django-simple-history on nested models package
Fixed bug when using django-simple-history on nested models package
Allow history table to be formatted correctly with django-admin-bootstrap
Disallow calling simple_history.register twice on the same model
Added Python 3 support
Added support for custom user model (Django 1.5+)
Fixed packaging bug: added admin template files to PyPI package
Fixed packaging bug: added admin template files to PyPI package
Nothing published for this version
Added history view/revert feature in admin interface
Added tests
Added history view/revert feature in admin interface
Various fixes and improvements
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →