可以通过Django的管理员监控django_admin_log吗?

时间:2010-02-10 21:46:56

标签: django django-admin

django_admin_log对于监控管理员中用户的操作非常有用。现在,我可以通过直接查询数据库来实现这一目标。是否有内置功能,我可以通过Django的管理员查看所有用户的表django_admin_log

4 个答案:

答案 0 :(得分:8)

不能只是:

from django.contrib.admin.models import LogEntry
admin.site.register(LogEntry)

在你的一个admin.py文件中?我只是测试它,它是准系统,但它的工作原理。

您可能希望更具体,并为LogEntry创建一个ModelAdmin类,以提供更好的列表视图和一些过滤功能。但这应该有用。

答案 1 :(得分:7)

这是我的版本。 Reference for fields available.

class LogAdmin(admin.ModelAdmin):
    """Create an admin view of the history/log table"""
    list_display = ('action_time','user','content_type','change_message','is_addition','is_change','is_deletion')
    list_filter = ['action_time','user','content_type']
    ordering = ('-action_time',)
    #We don't want people changing this historical record:
    def has_add_permission(self, request):
        return False
    def has_change_permission(self, request, obj=None):
        #returning false causes table to not show up in admin page :-(
        #I guess we have to allow changing for now
        return True
    def has_delete_permission(self, request, obj=None):
        return False

答案 2 :(得分:1)

这是一个更广泛的管理配置,用于查看依赖于Django 2.1仅查看权限的所有日志条目:

from django.contrib import admin
from django.contrib.admin.models import LogEntry, DELETION
from django.utils.html import escape
from django.utils.safestring import mark_safe
from django.urls import reverse

@admin.register(LogEntry)
class LogEntryAdmin(admin.ModelAdmin):
    date_hierarchy = 'action_time'
    readonly_fields = ('action_time',)
    list_filter = ['user', 'content_type']
    search_fields = ['object_repr', 'change_message']
    list_display = ['__str__', 'content_type', 'action_time', 'user', 'object_link']

    # keep only view permission
    def has_add_permission(self, request):
        return False

    def has_change_permission(self, request, obj=None):
        return False

    def has_delete_permission(self, request, obj=None):
        return False

    def object_link(self, obj):
        if obj.action_flag == DELETION:
            link = obj.object_repr
        else:
            ct = obj.content_type
            try:
                link = mark_safe('<a href="%s">%s</a>' % (
                                 reverse('admin:%s_%s_change' % (ct.app_label, ct.model),
                                         args=[obj.object_id]),
                                 escape(obj.object_repr),
                ))
            except NoReverseMatch:
                link = obj.object_repr
        return link
    object_link.admin_order_field = 'object_repr'
    object_link.short_description = 'object'

    def queryset(self, request):
        return super(LogEntryAdmin, self).queryset(request) \
            .prefetch_related('content_type')

它基于this Django snippet,结果如下:

screenshot of log entries

如果您想在早期的Django版本中使用它,请参阅此答案的this earlier revision

答案 3 :(得分:0)

根据我的经验几点:

  • 最好将所有字段都设为只读。 一个明显的原因是因为它们是日志,并且不应该可变,但是另一个原因是性能。例如,如果您允许更改用户,则在您拥有成千上万的用户的情况下,就可能无法单独加载更改页面。否则,您可以使用raw_id_fields
  • 内容类型过滤器值未按模型排序,因此不友好,但没有很好的通用解决方案可供共享。
  • 我还创建了动作过滤器,因为原始模型没有CHOICES字段,仅使用action_flag作为过滤器将显示1,2,3作为选择,这不是非常用户友好:

    class ActionFlagFilter(admin.SimpleListFilter):
        title = 'Action flag filter'
    
        parameter_name = 'action_flag'
    
        def lookups(self, request, model_admin):
            return (
                (ADDITION, "Add"),
                (CHANGE, "Change"),
                (DELETION, "Delete"),
            )
    
        def queryset(self, request, queryset):
            if self.value():
                return queryset.filter(action_flag=self.value())
            return queryset