Store model history and view/revert changes from admin site.
.. image:: https://github.com/jazzband/django-simple-history/actions/workflows/test.yml/badge.svg :target: https://github.com/jazzband/django-simple-history/actions/workflows/test.yml :alt: Build Status
.. image:: https://readthedocs.org/projects/django-simple-history/badge/?version=latest :target: https://django-simple-history.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status
.. image:: https://img.shields.io/codecov/c/github/jazzband/django-simple-history/master.svg :target: https://app.codecov.io/github/jazzband/django-simple-history?branch=master :alt: Test Coverage
.. image:: https://img.shields.io/pypi/v/django-simple-history.svg :target: https://pypi.org/project/django-simple-history/ :alt: PyPI Version
.. image:: https://api.codeclimate.com/v1/badges/66cfd94e2db991f2d28a/maintainability :target: https://codeclimate.com/github/jazzband/django-simple-history/maintainability :alt: Maintainability
.. image:: https://static.pepy.tech/badge/django-simple-history :target: https://pepy.tech/project/django-simple-history :alt: Downloads
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg :target: https://github.com/psf/black :alt: Code Style
.. image:: https://jazzband.co/static/img/badge.svg :target: https://jazzband.co/ :alt: Jazzband
django-simple-history stores Django model state on every create/update/delete.
This app supports the following combinations of Django and Python:
========== ======================== Django Python ========== ======================== 3.2 3.8, 3.9, 3.10 4.1 3.8, 3.9, 3.10, 3.11, 3.12-dev 4.2 3.8, 3.9, 3.10, 3.11, 3.12-dev main 3.10, 3.11, 3.12-dev ========== ========================
Documentation is available at https://django-simple-history.readthedocs.io/
Pull requests are welcome. Read the CONTRIBUTING_ file for tips on
submitting a pull request.
.. _CONTRIBUTING: https://github.com/jazzband/django-simple-history/blob/master/CONTRIBUTING.rst
This project is licensed under the
BSD 3-Clause license <https://choosealicense.com/licenses/bsd-3-clause/>_.
history model permissions explicitly when
SIMPLE_HISTORY_ENFORCE_HISTORY_MODEL_PERMISSIONS is set to True
in settings (gh-1017).SimpleHistoryAdmin not properly integrating with custom user models (gh-1177)bulk_update_with_history() return the number of model rows updated (gh-1206)HistoryRequestMiddleware not cleaning up after itself (i.e. deleting
HistoricalRecords.context.request) under some circumstances (gh-1188)HistoryRequestMiddleware async-capable (gh-1209)table_name with inherit=True (gh-1195)m2m_fields with model inheritance (gh-1042)pre_create_historical_m2m_records and post_create_historical_m2m_records (gh-1042)tracked_fields attribute to historical models (gh-1038)KeyError when running clean_duplicate_history on models with excluded_fields (gh-1038)--base-manager option to the clean_duplicate_history management command (gh-1115)bulk_create_with_history utility (gh-975)exists query instead of count in populate_history command (gh-982)Full list of changes:
Breaking Changes:
Upgrade Implications:
makemigrations after upgrading to realize the benefit of indexing changes.Full list of 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)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)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.
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)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)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)settings.SIMPLE_HISTORY_REVERT_DISABLED if True removes the Revert
button from the history form for all historical models (gh-632))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)BigAutoField not mirrored as BigInt (gh-556)most_recent() bug with excluded_fields (gh-561)six (gh-553)django.utils.six with six (gh-526)custom_model_name parameter to be a callable (gh-489)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.
app parameter to the constructor of HistoricalRecords (gh-486)custom_model_name parameter to the constructor of HistoricalRecords (gh-451)pre_create_historical_record to pass history_instance for ease of customization (gh-421)HistoricalRecords(inherit=False) is in an abstract model (gh-341)extra_context parameter to history_form_view (gh-467)next_record and prev_record to work with custom manager names (gh-501)'+' as the history_type for each instance in bulk_history_create (gh-449)history_change_reason for each instance in bulk_history_create (gh-449)history_change_reason in the history list view under the Change reason display name (gh-458)django_mongodb_engine when converting AutoFields (gh-432)HistoricalRecords (gh-244)bulk_create_with_history to allow bulk_create with history saved (gh-412)history_reason field (gh-379)history_id field (gh-368)prev_record and next_record (gh-365)history_view ignored user permissions (gh-361)HistoryRequestMiddleware which hadn't been working for Django>1.9 (gh-364)get_queryset rather than model.objects in history_view. (gh-303)--batchsize option to the populate_history management command. (gh-231)excluded_fields option to exclude fields from history. (gh-274)inherit=True. (gh-63)SIMPLE_HISTORY_EDIT setting.)to_field and db_column parameters (gh-182)CustomForeignKeyField (to be removed)auth.User for historical models (gh-121)ForeignKey with primary_key=Truelatestorder_with_respsect_to (gh-140)register()HistoryRequestMiddleware during anonymous requests (gh-115 fixes gh-114)as_of method to models as well as instances.history_user on historical objects to be set by middleware.history_datesimple_history should be added to INSTALLED_APPS (gh-94 fixes gh-69)django-simple-history on nested models packagedjango-admin-bootstrapsimple_history.register twice on the same model