By default, you can only see the action log ("History") for particular model instances and a list of your own actions on the admin's index. This adds a fully-fledged admin view for the LogEntry model, where you can filter actions by user, content type, action type, browse by change date, and also search in the change message.
Add the code to any of your apps' admin.py. The entries will be visible only to superusers and won't be editable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | from django.contrib.admin.models import LogEntry, DELETION from django.utils.html import escape from django.core.urlresolvers import reverse class LogEntryAdmin(admin.ModelAdmin): date_hierarchy = 'action_time' readonly_fields = LogEntry._meta.get_all_field_names() list_filter = [ 'user', 'content_type', 'action_flag' ] search_fields = [ 'object_repr', 'change_message' ] list_display = [ 'action_time', 'user', 'content_type', 'object_link', 'action_flag', 'change_message', ] def has_add_permission(self, request): return False def has_change_permission(self, request, obj=None): return request.user.is_superuser and request.method != 'POST' def has_delete_permission(self, request, obj=None): return False def object_link(self, obj): if obj.action_flag == DELETION: link = escape(obj.object_repr) else: ct = obj.content_type link = u'<a href="%s">%s</a>' % ( reverse('admin:%s_%s_change' % (ct.app_label, ct.model), args=[obj.object_id]), escape(obj.object_repr), ) return link object_link.allow_tags = True object_link.admin_order_field = 'object_repr' object_link.short_description = u'object' def queryset(self, request): return super(LogEntryAdmin, self).queryset(request) \ .prefetch_related('content_type') admin.site.register(LogEntry, LogEntryAdmin) |
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 3 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
Useful snippet! Thanks I think some small things are needed:
in imports from django.core.urlresolvers import reverse
change : object_link_field.allow_tags = True object_link_field.admin_order_field = 'object_repr' object_link_field.short_description = u'object'
to object_link.allow_tags = True object_link.admin_order_field = 'object_repr' object_link.short_description = u'object'
#
Thanks for pointing out the errors. It was copied from my project and I made some last changes introducing the errors here in the form. I've updated the snippet so it should work out of the box now.
#
When I put this in my app, it gave me a reverse error. To fix it, I had to change:
else: ct = obj.content_type link = u'%s' % ( reverse('admin:%s_%s_change' % (ct.app_label, ct.model), args=[obj.object_id]), escape(obj.object_repr), ) return link
to: else: ct = obj.content_type return u'
#
i would suggest adding an override for the queryset method to avoid a very large number of queries for content_type.
for me that reduces the number of queries from ~100 to ~8.
#
The comment by Zorpix was cut out by the "HTML-filtering" ('t was just code... should just HTML-escape it, right?)
Anyway, I used this snippet to much enjoyment, but also found issues:
list_filter
on all users was totally impractical, and scrolled over many screens.I made a few tweaks to get rid of these problems, and came up with this:
https://djangosnippets.org/snippets/3009/
#
A small fix, the import of reverse is now:
from django.urls import reverse
#
Please login first before commenting.