Django Models Logging
This package logs every change to your Django models in the following format:
{
"field_name": {
"old": "old_value",
"new": "new_value"
}
}
For deleted objects, "new" is omitted and only "old" is stored.
Example:
{
"price": {
"old": "2425",
"new": "645"
},
"name": {
"old": "ProductName",
"new": "NewProductName"
}
}
Requirements
- Python >= 3.10
- Django >= 5.2
Installation
- Install via pip:
pip install django-models-logging
- Add to
INSTALLED_APPS— must be at the end, after all apps whose models you want to log:
INSTALLED_APPS = [
...,
'models_logging',
]
- Run migrations:
python manage.py migrate
Configuration
Select models to log
LOGGING_MODELS = (
'app.ClassName', # log only this model
'another_app', # log all models in this app
)
Exclude models from logging
LOGGING_EXCLUDE = (
'app', # exclude all models in this app
'another_app.Model', # exclude a specific model
)
Custom user model
If request.user is not your AUTH_USER_MODEL:
LOGGING_USER_MODEL = 'yourapp.Users'
# default: AUTH_USER_MODEL
Per-model field filtering
Set these as class attributes on the model:
class MyModel(models.Model):
LOGGING_IGNORE_FIELDS = ('field1', 'field2') # exclude specific fields
# OR
LOGGING_ONLY_FIELDS = ('field1', 'field2') # include only these fields
Merging changes per request
By default, each .save() call creates a separate Change record. If .save() is called multiple times in one request, use the middleware to merge them:
MIDDLEWARE = [
...,
'models_logging.middleware.LoggingStackMiddleware',
]
To control merging independently of the middleware:
LOGGING_MERGE_CHANGES = True # default: True
For scripts or Celery tasks outside of a request cycle, use the context manager:
from models_logging.utils import create_merged_changes
def your_task():
with create_merged_changes():
...
To temporarily suppress logging entirely:
from models_logging.utils import ignore_changes
with ignore_changes(): # ignore all models
...
with ignore_changes([MyModel]): # ignore specific models
...
Logging bulk updates
queryset.update() does not trigger Django signals and is not logged automatically. Use create_changes_for_update instead:
from models_logging.utils import create_changes_for_update
create_changes_for_update(MyModel.objects.filter(active=True), active=False)
This captures old and new values for each affected row.
Admin
To show an object's change history in the Django admin, use HistoryAdmin:
from models_logging.admin import HistoryAdmin
class YourModelAdmin(HistoryAdmin):
history_latest_first = False # show oldest first (default)
inline_models_history = '__all__' # '__all__' or list of inline model classes
Admin permissions
def can_revert(request, obj):
return request.user.is_superuser
LOGGING_REVERT_IS_ALLOWED = can_revert # callable or bool, default: True
LOGGING_CAN_DELETE_REVISION = False # callable or bool, default: False
LOGGING_CAN_DELETE_CHANGES = False # callable or bool, default: False
LOGGING_CAN_CHANGE_CHANGES = False # callable or bool, default: False
LOGGING_CHANGES_REVISION_LIMIT = 100 # max changes shown inline in a revision
Custom JSON encoder
The default encoder handles FieldFile and GeoDjango Point types. To use your own:
LOGGING_JSON_ENCODER = 'path.to.your.JsonEncoder'
Custom change extras
To store extra data with each change (e.g. request IP, correlation ID), provide a custom function:
# yourapp/logging.py
def get_change_extras(obj, action):
from models_logging import _local
return {
'ip': getattr(_local, 'request', None) and _local.request.META.get('REMOTE_ADDR'),
}
LOGGING_GET_CHANGE_EXTRAS_FUNC = 'yourapp.logging.get_change_extras'
Management command
Delete old change records:
# delete all changes
python manage.py delete_changes
# delete changes for specific content types (by id)
python manage.py delete_changes --ctype 1,2,3
# exclude content types from deletion
python manage.py delete_changes --ctype-exclude 4,5
# delete changes older than a date
python manage.py delete_changes --date_lte 2024.01.01
Version compatibility
| Package version | Django | Python |
|---|---|---|
| 5.2.x | 5.2 | 3.10 – 3.14 |
| 2.x | 3.1 – 4.1 | 3.8+ |
| 0.9.7 | <= 2.0 | — |
Note: This package is not a database backup solution. Reverting thousands of changes will be slow.
Metadata
Release files for django-models-logging 5.2.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 | Provenance | |
|---|---|---|---|---|
| django_models_logging-5.2.0.tar.gz | 16.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_models_logging-5.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.4 kB
Release files / django_models_logging-5.2.0.tar.gz
| Download URL | django_models_logging-5.2.0.tar.gz |
|---|---|
| Size | 16.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
92ca584336e6565323623996ab270983ea0261c837859ca506721801b4914885
|
|
BLAKE2b-256 checksum How to use checksums |
c8a3b353d4d64dbb50adae5fd988242d4b5c34c4af1bc16b9508bd1883ac93de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","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_models_logging-5.2.0-py3-none-any.whl
| Download URL | django_models_logging-5.2.0-py3-none-any.whl |
|---|---|
| Size | 27.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
80a5e52e8d7da03d8b2ee87fa8c35301eebe8b2c5fe05dbd1a465a8de5b52150
|
|
BLAKE2b-256 checksum How to use checksums |
81e03afd25144eca4c2576d5a527ef40881b12c72c0b2c335bf81492caaf9ad4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","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}
|
Security for django-models-logging 5.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.