Simple Audit Models

Audit Models

The idea behind an audit model is to track the date and time a record was created or updated, and the user that performed the action. Automatically setting the date and time on a model instance is not hard, but recording the added by and modified by poses a challenge. It would be nice to simply override the save() method of the model, but there is no access to the current request and therefore the current user. (Even if request was passed to save, it would be unavailable to things like management commands).

There are many possible approaches to this problem.

The Simplest Thing That Works

The simplest form of auditing available in Django is to provide:

  1. The user that created the record and the date/time the record was created.
  2. The user that last modified the record and the date/time the record was last modified.

This, of course, does not provide a history of changes to a record but provides some basic points of reference and may be suitable as minimum viable auditing.

Implementing record history will be the subject of a future article.

SuperDjango DB Audit

SuperDjango provides two classes for implementing a simple audit system:

  • AddedByModel: Provides added_by and added_dt.
  • ModifiedByModel: Provides modified_by and modified_dt.

Both models include an audit() method.

In this example a task extends both abstract models:

from superdjango.db.audit.models import AddedByModel, ModifiedByModel

class Task(AddedByModel, ModifiedByModel):
    description = models.TextField(blank=True, null=True)
    due_date = models.DateField(blank=True, null=True)
    title = models.CharField(max=128)

The save_model() method must be overridden for the admin:

from django.contrib import admin
from superdjango.db.audit import BaseAuditModelAdmin
from .models import Task

@admin.register(Task)
class TaskAdmin(BaseAuditModelAdmin):
    # ...

    def save_model(self, request, obj, form, change):
        obj.audit(request.user, commit=False)
        super().save_model(request, obj, form, change)

If you are using SuperDjango UI, the audit information is automatically saved when the record is created or updated.



Posted in Database by Shawn Davis, March 15, 2020