Skip to content

Instantly share code, notes, and snippets.

@shacker

shacker/admin.py

Last active Apr 11, 2017
Embed
What would you like to do?
ORM Logging boilerplate
from dirapp.models import Log
from django.contrib import admin
class LogAdmin(admin.ModelAdmin):
search_fields = ['user__username', 'action']
list_display = ('user', 'anon_username', 'action', 'target', 'status', 'ip_addr', 'timestamp',)
list_filter = ['target', 'status']
admin.site.register(Log, LogAdmin)
from django.contrib.auth.models import User
from django.db import models
class Log(models.Model):
'''
Keep track of every action that changes data anywhere.
All activities are associated with the person who executed them.
However, some activities are done by unauthenticated users (Activate Account, Forgot Passphrase),
so we can't always FK to the user (since they don't exist in our Users table).
For those actions, we'll use a shared "anon" User record, but will also store the username
that was acted upon in a separate field.
'''
TARGET_CHOICES = (
(u'L', u'LDAP'),
(u'G', u'Google'),
(u'W', u'Workday'),
)
STATUS_CHOICES = (
(u'S', u'Success'),
(u'F', u'Failure'),
(u'I', u'Info'),
)
user = models.ForeignKey(User)
anon_username = models.CharField(blank=True, max_length=50)
action = models.CharField(max_length=255, help_text="")
target = models.CharField(max_length=1, choices=TARGET_CHOICES, blank=True)
status = models.CharField(max_length=1, choices=STATUS_CHOICES, default="S")
ip_addr = models.GenericIPAddressField(blank=True, null=True)
timestamp = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
if self.user.username == "anon":
user = self.anon_username
else:
user = self.user
return "{d}: {a} in {t} (by {u})".format(
d="{:%m/%d/%y %I:%M %p}".format(self.timestamp),
u=user,
a=self.action,
t=self.get_target_display()
)
from myapp.models import Log
def log_action(request, user=None, anon_username='', action='', target='', ip_addr='', status='S'):
'''
Write a log line for every action that alters data.
Takes either a User object or an anonymous username,
an "action" string and a target system specified as "L", "G" or "W"
(see choices in the model). Default status is "Success" - pass in status: "F"
or status: "I" for failure or info.
'''
# Handle anonymous log entries - attach to 'anon' user, creating if it doesn't exist
# Django considers a non-auth user here `is_anonymous()`.
if not user or user.is_anonymous():
user, created = User.objects.get_or_create(username='anon')
ip_addr = get_client_ip(request)
Log.objects.create(
user=user, anon_username=anon_username, action=action,
target=target, ip_addr=ip_addr, status=status)
from myapp.utils import log_action
# invoke in the context of views like:
success_msg = "{u} successfully created LDAP account".format(u=request.user)
log_action(request, anon_username=username, target="L", status="S", action=success_msg)
# or
failure_msg = "{u} failed to create GMail account".format(u=request.user)
log_action(request, anon_username=username, target="G", status="F", action=failure_msg)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment