Skip to main content

Add logging of models from save, delete signals

Project description

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

  1. Install via pip:
pip install django-models-logging
  1. Add to INSTALLED_APPS — must be at the end, after all apps whose models you want to log:
INSTALLED_APPS = [
    ...,
    'models_logging',
]
  1. 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_models_logging-5.2.0.tar.gz (16.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_models_logging-5.2.0-py3-none-any.whl (27.5 kB view details)

Uploaded Python 3

File details

Details for the file django_models_logging-5.2.0.tar.gz.

File metadata

  • Download URL: django_models_logging-5.2.0.tar.gz
  • Upload date:
  • Size: 16.9 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for django_models_logging-5.2.0.tar.gz
Algorithm Hash digest
SHA256 92ca584336e6565323623996ab270983ea0261c837859ca506721801b4914885
MD5 001547dc438f1958c50232f474eb54e9
BLAKE2b-256 c8a3b353d4d64dbb50adae5fd988242d4b5c34c4af1bc16b9508bd1883ac93de

See more details on using hashes here.

File details

Details for the file django_models_logging-5.2.0-py3-none-any.whl.

File metadata

  • Download URL: django_models_logging-5.2.0-py3-none-any.whl
  • Upload date:
  • Size: 27.5 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for django_models_logging-5.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 80a5e52e8d7da03d8b2ee87fa8c35301eebe8b2c5fe05dbd1a465a8de5b52150
MD5 e108bc619970a4d90fba05a84620c543
BLAKE2b-256 81e03afd25144eca4c2576d5a527ef40881b12c72c0b2c335bf81492caaf9ad4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page