Django - 自定义管理功能日志记录

18 投票
3 回答
15446 浏览
提问于 2025-04-17 19:03

在Django的管理后台,你所做的所有更改都会记录在一个叫做django_admin_table的表里,你还可以在“最近的操作”中看到你最近的更改。

但是,当你自己写“管理操作”并通过这些操作进行更改时,默认情况下是不会记录这些操作的。

举个例子:

def make_checked(modeladmin, request, queryset):
    queryset.update(checked = 1)
make_checked.short_description = 'Mark selected products as checked'

我现在的问题是,是否可以记录自定义的管理操作,如果可以的话,应该怎么做呢?

3 个回答

2

谢谢!经过一些小改动后,效果很好:

def make_checked(modeladmin, request, queryset):
    queryset.update(checked = 1)

    ct = ContentType.objects.get_for_model(queryset.model) # for_model --> get_for_model
    for obj in queryset:
        LogEntry.objects.log_action( # log_entry --> log_action
            user_id = request.user.id,
            content_type_id = ct.pk,
            object_id = obj.pk,
            object_repr = obj.title,
            action_flag = CHANGE, # actions_flag --> action_flag
            change_message = 'Changed checked.')
make_checked.short_description = 'Mark selected products as checked'
13

其实现在有一种比之前的答案简单得多的方法,只要你有一个 ModelAdmin 可用,这在自定义操作的情况下是有的。

ModelAdmin 类的文档不是很好,但它实际上提供了这些方法作为快捷方式:

def log_addition(self, request, object, message):
    """
    Log that an object has been successfully added.

    The default implementation creates an admin LogEntry object.
    """

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.

    The default implementation creates an admin LogEntry object.
    """

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method must be
    called before the deletion.

    The default implementation creates an admin LogEntry object.
    """

这些方法使用起来非常简单。接着用问题中的例子来说明:

def make_checked(modeladmin, request, queryset):
    queryset.update(checked = 1)
    for obj in queryset:
        modeladmin.log_change(request, obj, 'Marked checked: ' + str(obj))
make_checked.short_description = 'Mark selected products as checked'
28

看看管理员的 LogEntry 模型,更重要的是 LogEntryManager。这个模型管理器提供了一个 log_action 方法,可以方便地添加你自己的日志条目(虽然这个代码没有经过测试,但应该能让你明白这个概念):

from django.contrib.admin.models import LogEntry, CHANGE
from django.contrib.contenttypes.models import ContentType

def make_checked(modeladmin, request, queryset):
    queryset.update(checked = 1)

    ct = ContentType.objects.get_for_model(queryset.model)
    for obj in queryset:
        LogEntry.objects.log_action(
            user_id=request.user.id, 
            content_type_id=ct.pk,
            object_id=obj.pk,
            object_repr=obj.description,
            action_flag=CHANGE,
            change_message="You have ...") 
make_checked.short_description = 'Mark selected products as checked'

你可以在正常的 Django 管理界面中看到一些 使用日志记录的例子。如果你只想为整个查询集添加一个 LogEntry,你可以手动完成(因为上面的 log_entry 需要一组特定的参数,适用于记录单个对象):

l = LogEntry(user_id=request.user.id, actions_flag=CHANGE, change_message="...")
l.save()

撰写回答