Package: django-history-triggers
django-history-triggersdjango-history-triggersis a Django application for installing database triggers
that automatically record inserts, updates, and deletes to model tables.RequirementsDjango 3.2+PostgreSQL or SQLite databaseInstallationpip install django-history-triggersQuick StartAddhistoryto your INSTALLED_APPS setting and migrate your database.Addhistory.middleware.HistoryMiddlewareto the end of yourMIDDLEWAREsetting.Runmanage.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.SettingsHISTORY_MODEL(default:"history.ObjectHistory")HISTORY_IGNORE_APPS(default:["admin", "contenttypes", "sessions"])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 SessionsHistory 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:fromhistoryimportget_backenddefapi_view(request):# You can pass extra fields to be stored for all history within a session.withget_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:withget_backend().session()assession:Model.objects.create(name="This history is recorded")withsession.paused():Model.objects.create(name="This history is NOT recorded")Model.objects.create(name="This history is also recorded")Custom History ModelThe defaulthistory.ObjectHistorymodel is swappable by changing theHISTORY_MODELsetting. If you need to define your own object history model (usually for tracking
custom fields or non-standard user info), be sure to inherit fromhistory.models.AbstractObjectHistory. If at all possible, do this early on to avoid
problems with migrations when changingHISTORY_MODELafter the initial migration.Filtering HistoryTheHISTORY_FILTERsetting 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:Thedjango.db.models.Modelclass being filteredThedjango.db.models.fields.Fieldinstance in questionThehistory.models.TriggerTypebeing createdThe filter should returnTrueif the field should be included, andFalseif it
should be excluded. The default implementation (history.utils.default_filter) simply
includes any field exceptBinaryFields:defdefault_filter(model,field,trigger_type):returnnotisinstance(field,models.BinaryField)ReturningFalsefor all fields of any given model has the effect of not tracking
history for that model:deffilter_sensitive(model,field,trigger_type):returnnotissubclass(model,SensitiveDataModel)Similarly, if you (for example) only wanted to record history for UPDATE statements:defupdates_only(model,field,trigger_type):returntrigger_type==TriggerType.UPDATEManagement CommandsBy defaultdjango-history-triggersdoes not override any of Django's management
commands that may perform database operations, such asloaddataormigrate. If you
need to run these commands with history triggers enabled, you can include the following
apps in yourINSTALLED_APPSsetting:history.contrib.loaddatahistory.contrib.migrateTheHISTORY_LOADDATA_CONTEXTandHISTORY_MIGRATE_CONTEXTsettings control the
history session context for the respective command, for example:HISTORY_MIGRATE_CONTEXT={"user":"system"}