You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST接入LogEntry记录用户活动及Token认证下查询变更问题

核心问题原因

Django内置的LogEntry默认仅自动记录Admin站点内的操作,你通过SimpleJWT认证访问DRF接口的操作,默认不会触发LogEntry的写入逻辑,因此查询不到对应变更数据。

解决方案

1. 实现接口操作自动写入LogEntry

通过DRF自定义Mixin实现通用日志逻辑,不需要为每个接口的每个方法单独写代码:
首先创建通用日志混入类:

# mixins.py
from django.contrib.admin.models import LogEntry, ADDITION, CHANGE, DELETION
from django.contrib.contenttypes.models import ContentType

class AutoLogMixin:
    def perform_create(self, serializer):
        instance = serializer.save()
        content_type = ContentType.objects.get_for_model(instance)
        LogEntry.objects.log_action(
            user_id=self.request.user.id,
            content_type_id=content_type.pk,
            object_id=instance.pk,
            object_repr=str(instance),
            action_flag=ADDITION,
            change_message="API创建资源"
        )
        return instance

    def perform_update(self, serializer):
        instance = serializer.save()
        content_type = ContentType.objects.get_for_model(instance)
        LogEntry.objects.log_action(
            user_id=self.request.user.id,
            content_type_id=content_type.pk,
            object_id=instance.pk,
            object_repr=str(instance),
            action_flag=CHANGE,
            change_message="API更新资源"
        )
        return instance

    def perform_destroy(self, instance):
        content_type = ContentType.objects.get_for_model(instance)
        object_repr = str(instance)
        # 删除前先写入日志,避免实例删除后无法获取属性
        LogEntry.objects.log_action(
            user_id=self.request.user.id,
            content_type_id=content_type.pk,
            object_id=instance.pk,
            object_repr=object_repr,
            action_flag=DELETION,
            change_message="API删除资源"
        )
        instance.delete()

之后所有需要记录日志的业务ViewSet,直接继承该Mixin即可自动记录增删改操作:

# 业务ViewSet示例
class YourBusinessViewSet(AutoLogMixin, viewsets.ModelViewSet):
    queryset = YourModel.objects.all()
    serializer_class = YourModelSerializer

如果需要全项目所有接口都生效,直接修改你项目的公共BaseViewSet,让所有业务ViewSet继承的基类先继承AutoLogMixin即可,无需逐个修改。

2. 适配SimpleJWT认证的LogEntry查询接口

修改你现有的LogEntryViewSet,启用JWT认证,同时可以按用户权限返回对应日志:

# viewsets.py
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication

class LogEntryViewSet(viewsets.ModelViewSet):
    # 启用JWT认证
    authentication_classes = [JWTAuthentication]
    # 要求登录才可访问
    permission_classes = [IsAuthenticated]
    serializer_class = LogEntrySerializer

    def get_queryset(self):
        user = self.request.user
        # 超级管理员可查看所有日志
        if user.is_superuser:
            return LogEntry.objects.all()
        # 普通用户仅查看自身操作生成的日志
        return LogEntry.objects.filter(user=user)

可选优化

如果需要记录具体字段变更内容,可在perform_update方法中加入新旧字段对比逻辑,将差异内容写入change_message字段即可。

内容的提问来源于stack exchange,提问作者elias_oliveira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 09:27:00