django-history-triggers
django-history-triggers is a Django application for installing database triggers
that automatically record inserts, updates, and deletes to model tables.
Requirements
- Django 4.2+
- PostgreSQL or SQLite database
Warning: there is a bug in SQLite 3.45.1 that causes JSON changes to be stored as strings. Unfortunately, this is the version that ships with Ubuntu 24.04.
Installation
pip install django-history-triggers
Quick Start
- Add
historyto your INSTALLED_APPS setting and migrate your database. - Add
history.middleware.HistoryMiddlewareto the end of yourMIDDLEWAREsetting. - Run
manage.py triggers enableto install the trigger functions, ormanage.py triggers disableto uninstall them. Neither will clear existing history data -- add a--clearoption to do that.
Settings
HISTORY_MODEL(default:"history.ObjectHistory")HISTORY_IGNORE_APPS(default:["admin", "contenttypes", "sessions"])HISTORY_IGNORE_MODELS(default[]- should be lowercaseapp_label.model_name)HISTORY_MIDDLEWARE_IGNORE(default:[])HISTORY_FILTER(default:"history.utils.default_filter")HISTORY_REQUEST_CONTEXT(default:"history.utils.get_request_context")HISTORY_ADMIN_ENABLED(default:True)HISTORY_INCLUDE_UNMANAGED(default:True)
History Sessions
History is recorded within "sessions" that you can manage manually, either outside of a web request context, or in place of or in addition to the included middleware. The easiest way to manage a history session is via a context manager:
from history import get_backend
def api_view(request):
# You can pass extra fields to be stored for all history within a session.
with get_backend().session(user=request.user, path=request.path):
# All history inside here will have the same session_id and session_date.
...
Starting in 3.4.2, you can also "pause" history recording within a session:
with get_backend().session() as session:
Model.objects.create(name="This history is recorded")
with session.paused():
Model.objects.create(name="This history is NOT recorded")
Model.objects.create(name="This history is also recorded")
Custom History Model
The default history.ObjectHistory model is swappable by changing the HISTORY_MODEL
setting. If you need to define your own object history model (usually for tracking
custom fields or non-standard user info), be sure to inherit from
history.models.AbstractObjectHistory. If at all possible, do this early on to avoid
problems with migrations when changing HISTORY_MODEL after the initial migration.
Filtering History
The HISTORY_FILTER setting allows you to fully customize which fields (or even whole
models) should be included in or excluded from history. It is implemented as a callable
that takes three parameters:
- The
django.db.models.Modelclass being filtered - The
django.db.models.fields.Fieldinstance in question - The
history.models.TriggerTypebeing created
The filter should return True if the field should be included, and False if it
should be excluded. The default implementation (history.utils.default_filter) simply
includes any field except BinaryFields:
def default_filter(model, field, trigger_type):
return not isinstance(field, models.BinaryField)
Returning False for all fields of any given model has the effect of not tracking
history for that model:
def filter_sensitive(model, field, trigger_type):
return not issubclass(model, SensitiveDataModel)
Similarly, if you (for example) only wanted to record history for UPDATE statements:
def updates_only(model, field, trigger_type):
return trigger_type == TriggerType.UPDATE
Management Commands
By default django-history-triggers does not override any of Django's management
commands that may perform database operations, such as loaddata or migrate. If you
need to run these commands with history triggers enabled, you can include the following
apps in your INSTALLED_APPS setting:
history.contrib.loaddatahistory.contrib.migrate
The HISTORY_LOADDATA_CONTEXT and HISTORY_MIGRATE_CONTEXT settings control the
history session context for the respective command, for example:
HISTORY_MIGRATE_CONTEXT = {"user": "system"}
Metadata
Release files for django-history-triggers 3.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_history_triggers-3.6.0.tar.gz | 12.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_history_triggers-3.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.6 kB
Release files / django_history_triggers-3.6.0.tar.gz
| Download URL | django_history_triggers-3.6.0.tar.gz |
|---|---|
| Size | 12.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ed95bc728fed9ba1e516d48e82d1bf759217346230476e0930060171d11da488
|
|
BLAKE2b-256 checksum How to use checksums |
d4dab19580e67864e22038e76e7379ae676bf709d08d062d2bc3ab3b12fadda0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_history_triggers-3.6.0-py3-none-any.whl
| Download URL | django_history_triggers-3.6.0-py3-none-any.whl |
|---|---|
| Size | 21.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b9cc3634c79ce19fbdcc2418250f82a841179238f6109d2ccb923573b17c2372
|
|
BLAKE2b-256 checksum How to use checksums |
122082c54be92e7e392b9fc99a0f2fb52a7123ed4948066e11752e43f2e7b10a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|