1. Michael Hall
  2. django-audit

Wiki

Clone wiki

django-audit / Home

About Django-Audit

Django-Audit is a set of Django middleware, models and signals that provide transparent auditing of all changes made to data through your Model classes.

Changes made through an audited model is saved to the audit_log table. This table stores the timestamp of the change, the Django user id of the user making the request, the application's name, the model's name, the model's primary key id, the field that was changed, and the old and new values for that field.

Installing

In order for automated auditing to capture user information, you need to install the auditing middleware as show here:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'audit.middleware.CaptureRequestUser',
)

You will also need to add the audit app to your list of installed apps, so that Django will process it's models:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'audit',
 )

Models

The easiest way to add auditing to your models is to subclass the AuditModel class. This class is itself a subclass of django.db.models.Model, and will intercept calls to save() and delete() to record the previous and new values of the model's fields.

import audit

class Widget(audit.models.AuditModel):
    
    class Meta:
        verbose_name = "Simple Widget"
    
    WIDGET_SIZES = [(0, u'Small'), (1, u'Medium'), (2, u'Large')]
    
    number = models.PositiveIntegerField("Widget #", unique=True)
    name = models.CharField("Name", max_length=64)
    size = models.PositiveSmallIntegerField("Type", choices=WIDGET_SIZES)

Ignored Fields

By default, Django-Audit will save changes to all fields in a model. However, sometimes there will be fields in a model that you do not want to be recorded in the audit log, such as passwords. In those cases, you can add a list of fields to ignore to audit_ignore in your model like this:

class MyUser(audit.models.AuditModel, django.contrib.auth.models.User):
    
    class Meta:
        verbose_name = _("User")
        ordering = ('last_name', 'first_name')
        
    audit_ignore = ['password']

    Address1 = models.CharField(max_length=64, blank=True, null=True)
    Address2 = models.CharField(max_length=64, blank=True, null=True)
    City = models.CharField(max_length=64, blank=True, null=True)
    State = models.CharField(max_length=2, blank=True, null=True)
    Zip = models.CharField(max_length=10, blank=True, null=True)
    WorkPhone = models.CharField("Work Phone", max_length=13, blank=True, null=True)
    MobilePhone = models.CharField("Mobile Phone", max_length=13, blank=True, null=True)
    EMailAddress = models.EmailField("Email Address", blank=True, null=True)

Censored Fields

Similar to ignored_fields, you can provide a list of field names that you want to audit the fact that a change was made, but you do not want the values of the change to be recorded, in the censored_fields array in the mode. Censored fields will have both their old and new values replaced with *s in the audit_log table.

Signals

You can add auditing to existing models without deriving from AuditModel by connecting them with Django signals.

from audit.signals import auditSave, auditDelete
from django.db.models.signals import pre_save, pre_delete

pre_save.connect(auditSave, sender=YourObject)
pre_delete.connect(auditDelete, sender=YourObject)

Updated