Quick Start
Install
Install from PyPI with pip
:
$ pip install django-simple-history
Configure
Settings
Add simple_history
to your INSTALLED_APPS
INSTALLED_APPS = [
# ...
'simple_history',
]
The historical models can track who made each change. To populate the
history user automatically you can add HistoryRequestMiddleware
to your Django
settings:
MIDDLEWARE = [
# ...
'simple_history.middleware.HistoryRequestMiddleware',
]
If you do not want to use the middleware, you can explicitly indicate the user making the change as documented in User Tracking.
Track History
To track history for a model, create an instance of
simple_history.models.HistoricalRecords
on the model.
An example for tracking changes on the Poll
and Choice
models in the
Django tutorial:
from django.db import models
from simple_history.models import HistoricalRecords
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
history = HistoricalRecords()
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
history = HistoricalRecords()
Now all changes to Poll
and Choice
model instances will be tracked in
the database.
Track History for a Third-Party Model
To track history for a model you didn’t create, use the
simple_history.register
function. You can use this to track models from
third-party apps you don’t have control over. Here’s an example of using
simple_history.register
to history-track the User
model from the
django.contrib.auth
app:
from simple_history import register
from django.contrib.auth.models import User
register(User)
If you want to separate the migrations of the historical model into an app other than
the third-party model’s app, you can set the app
parameter in
register
. For instance, if you want the migrations to live in the migrations
folder of the package you register the model in, you could do:
register(User, app=__package__)
Run Migrations
With your model changes in place, create and apply the database migrations:
$ python manage.py makemigrations
$ python manage.py migrate
Existing Projects
For existing projects, you can call the populate command to generate an initial change for preexisting model instances:
$ python manage.py populate_history --auto
By default, history rows are inserted in batches of 200. This can be changed if needed for large tables
by using the --batchsize
option, for example --batchsize 500
.
What Now?
By adding HistoricalRecords
to a model or registering a model using register
,
you automatically start tracking any create, update, or delete that occurs on that model.
Now you can query the history programmatically
and view the history in Django admin.
What is django-simple-history
Doing Behind the Scenes?
If you tried the code above and ran the migrations on it, you’ll see the following tables in your database:
app_choice
app_historicalchoice
app_historicalpoll
app_poll
The two extra tables with historical
prepend to their names are tables created
by django-simple-history
. These tables store every change that you make to their
respective base tables. Every time a create, update, or delete occurs on Choice
or
Poll
a new row is created in the historical table for that model including all of
the fields in the instance of the base model, as well as other metadata:
history_user
: the user that made the create/update/deletehistory_date
: thedatetime
at which the create/update/delete occurredhistory_change_reason
: the reason the create/update/delete occurred (null by default)history_id
: the primary key for the historical table (note the base table’s primary key is not unique on the historical table since there are multiple versions of it on the historical table)history_type
:+
for create,~
for update, and-
for delete
Now try saving an instance of Choice
or Poll
. Check the historical table
to see that the history is being tracked.