Last active
April 11, 2017 06:17
-
-
Save shacker/05bc1de527a2d7412de361ac659aecde to your computer and use it in GitHub Desktop.
ORM Logging boilerplate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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