import django
from django.contrib import admin
from django.contrib.admin.models import LogEntry, ADDITION, CHANGE, DELETION
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse, NoReverseMatch
from django.utils.encoding import force_text
from django.utils.html import escape
from django.utils.translation import ugettext_lazy as _
# Admin for LogEntry, maaybe move to standalone app? based on https://github.com/yprez/django-logentry-admin
action_names = {
ADDITION: _('Addition'),
DELETION: _('Deletion'),
CHANGE: _('Change'),
}
[docs]class ActionListFilter(admin.SimpleListFilter):
title = _('Action')
parameter_name = 'action_flag'
[docs] def lookups(self, request, model_admin):
return action_names.items()
[docs] def queryset(self, request, queryset):
if self.value():
queryset = queryset.filter(action_flag=self.value())
return queryset
[docs]class UserListFilter(admin.SimpleListFilter):
title = _('staff user')
parameter_name = 'user'
[docs] def lookups(self, request, model_admin):
staff = get_user_model().objects.filter(is_staff=True)
return (
(s.id, force_text(s))
for s in staff
)
[docs] def queryset(self, request, queryset):
if self.value():
queryset = queryset.filter(user_id=self.value(),
user__is_staff=True)
return queryset
[docs]class LogEntryAdmin(admin.ModelAdmin):
date_hierarchy = 'action_time'
readonly_fields = ([f.name for f in LogEntry._meta.fields] +
['object_link', 'action_description', 'user_link',
'get_change_message'])
fieldsets = (
(_('Metadata'), {
'fields': (
'action_time',
'user_link',
'action_description',
'object_link',
)
}),
(_('Detail'), {
'fields': (
'get_change_message',
'content_type',
'object_id',
'object_repr',
)
}),
)
list_filter = [
UserListFilter,
'content_type',
ActionListFilter
]
search_fields = [
'object_repr',
'change_message'
]
list_display_links = [
'action_time',
'get_change_message',
]
list_display = [
'action_time',
'user_link',
'content_type',
'object_link',
'action_description',
'get_change_message',
]
[docs] def has_add_permission(self, request):
return False
[docs] def has_change_permission(self, request, obj=None):
return (
request.user.is_superuser or
request.user.has_perm('admin.change_logentry')
) and request.method != 'POST'
[docs] def has_delete_permission(self, request, obj=None):
return False
[docs] def object_link(self, obj):
object_link = escape(obj.object_repr)
content_type = obj.content_type
if obj.action_flag != DELETION and content_type is not None:
# try returning an actual link instead of object repr string
try:
url = reverse(
'admin:{}_{}_change'.format(content_type.app_label,
content_type.model),
args=[obj.object_id]
)
object_link = '<a href="{}">{}</a>'.format(url, object_link)
except NoReverseMatch:
pass
return object_link
object_link.allow_tags = True
object_link.admin_order_field = 'object_repr'
object_link.short_description = _('object')
[docs] def user_link(self, obj):
content_type = ContentType.objects.get_for_model(type(obj.user))
user_link = escape(force_text(obj.user))
try:
# try returning an actual link instead of object repr string
url = reverse(
'admin:{}_{}_change'.format(content_type.app_label,
content_type.model),
args=[obj.user.pk]
)
user_link = '<a href="{}">{}</a>'.format(url, user_link)
except NoReverseMatch:
pass
return user_link
user_link.allow_tags = True
user_link.admin_order_field = 'user'
user_link.short_description = _('user')
[docs] def get_queryset(self, request):
queryset = super(LogEntryAdmin, self).get_queryset(request)
return queryset.prefetch_related('content_type')
[docs] def get_actions(self, request):
actions = super(LogEntryAdmin, self).get_actions(request)
if 'delete_selected' in actions:
del actions['delete_selected']
return actions
[docs] def action_description(self, obj):
return action_names[obj.action_flag]
action_description.short_description = _('Action')
[docs] def get_change_message(self, obj):
if django.VERSION >= (1, 10):
return obj.get_change_message()
return obj.change_message
get_change_message.short_description = _('change message')
admin.site.register(LogEntry, LogEntryAdmin)