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=True
latest
order_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_date
simple_history
should be added to INSTALLED_APPS
(gh-94 fixes gh-69)django-simple-history
on nested models packagedjango-admin-bootstrap
simple_history.register
twice on the same model