mirror of
https://github.com/jazzband/django-auditlog.git
synced 2026-03-16 22:20:26 +00:00
enhanced admin interface closes #1
This commit is contained in:
parent
f08b4a7dac
commit
20eb91359a
4 changed files with 87 additions and 4 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -3,3 +3,5 @@
|
|||
*.pyc
|
||||
*.db
|
||||
local_settings.py
|
||||
.pydevproject
|
||||
.project
|
||||
|
|
|
|||
|
|
@ -1,9 +1,18 @@
|
|||
from django.contrib import admin
|
||||
from .models import LogEntry
|
||||
from .mixins import LogEntryAdminMixin
|
||||
from .filters import ResourceTypeFilter
|
||||
|
||||
|
||||
class LogEntryAdmin(admin.ModelAdmin, LogEntryAdminMixin):
|
||||
list_display = ['created', 'resource_url', 'action', 'msg_short', 'user_url']
|
||||
search_fields = ['timestamp', 'object_repr', 'changes', 'actor__full_name']
|
||||
list_filter = ['action', ResourceTypeFilter]
|
||||
readonly_fields = ['created', 'resource_url', 'action', 'user_url', 'msg']
|
||||
fieldsets = [
|
||||
(None, {'fields': ['created', 'user_url', 'resource_url']}),
|
||||
('Changes', {'fields': ['action', 'msg']}),
|
||||
]
|
||||
|
||||
class LogEntryAdmin(admin.ModelAdmin):
|
||||
list_display = ('object_pk', 'object_repr', 'actor', 'action', 'changes', 'timestamp')
|
||||
list_filter = ('content_type',)
|
||||
|
||||
admin.site.register(LogEntry, LogEntryAdmin)
|
||||
|
||||
|
|
|
|||
16
src/auditlog/filters.py
Normal file
16
src/auditlog/filters.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
from django.contrib.admin import SimpleListFilter
|
||||
|
||||
|
||||
class ResourceTypeFilter(SimpleListFilter):
|
||||
title = 'Resource Type'
|
||||
parameter_name = 'resource_type'
|
||||
|
||||
def lookups(self, request, model_admin):
|
||||
qs = model_admin.get_queryset(request)
|
||||
types = qs.values_list('content_type_id', 'content_type__model')
|
||||
return list(types.order_by('content_type__model').distinct())
|
||||
|
||||
def queryset(self, request, queryset):
|
||||
if self.value() is None:
|
||||
return queryset
|
||||
return queryset.filter(content_type_id=self.value())
|
||||
56
src/auditlog/mixins.py
Normal file
56
src/auditlog/mixins.py
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import json
|
||||
|
||||
from django.conf import settings
|
||||
from django.core import urlresolvers
|
||||
|
||||
MAX = 75
|
||||
|
||||
|
||||
class LogEntryAdminMixin(object):
|
||||
|
||||
def created(self, obj):
|
||||
return obj.timestamp.strftime('%Y-%m-%d %H:%M:%S')
|
||||
created.short_description = 'Created'
|
||||
|
||||
def user_url(self, obj):
|
||||
if obj.actor:
|
||||
app_label, model = settings.AUTH_USER_MODEL.split('.')
|
||||
viewname = 'admin:%s_%s_change' % (app_label, model.lower())
|
||||
link = urlresolvers.reverse(viewname, args=[obj.actor.id])
|
||||
return u'<a href="%s">%s</a>' % (link, obj.actor.full_name or obj.actor.email)
|
||||
return 'system'
|
||||
user_url.allow_tags = True
|
||||
user_url.short_description = 'User'
|
||||
|
||||
def resource_url(self, obj):
|
||||
app_label, model = obj.content_type.app_label, obj.content_type.model
|
||||
viewname = 'admin:%s_%s_change' % (app_label, model)
|
||||
link = urlresolvers.reverse(viewname, args=[obj.object_id])
|
||||
return u'<a href="%s">%s</a>' % (link, obj.object_repr)
|
||||
resource_url.allow_tags = True
|
||||
resource_url.short_description = 'Resource'
|
||||
|
||||
def msg_short(self, obj):
|
||||
if obj.action == 2:
|
||||
return '' # delete
|
||||
changes = json.loads(obj.changes)
|
||||
s = '' if len(changes) == 1 else 's'
|
||||
fields = ', '.join(changes.keys())
|
||||
if len(fields) > MAX:
|
||||
i = fields.rfind(' ', 0, MAX)
|
||||
fields = fields[:i] + ' ..'
|
||||
return '%d change%s: %s' % (len(changes), s, fields)
|
||||
msg_short.short_description = 'Changes'
|
||||
|
||||
def msg(self, obj):
|
||||
if obj.action == 2:
|
||||
return '' # delete
|
||||
changes = json.loads(obj.changes)
|
||||
msg = '<table><tr><th>#</th><th>Field</th><th>From</th><th>To</th></tr>'
|
||||
for i, field in enumerate(sorted(changes), 1):
|
||||
value = [i, field] + (['***', '***'] if field == 'password' else changes[field])
|
||||
msg += '<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>' % tuple(value)
|
||||
msg += '</table>'
|
||||
return msg
|
||||
msg.allow_tags = True
|
||||
msg.short_description = 'Changes'
|
||||
Loading…
Reference in a new issue