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

Django DRF接口未触发has_object_permission方法的问题排查

问题解决:DRF中APIView未触发has_object_permission的修复方案

DRF的has_object_permission方法仅在视图成功获取到具体对象实例后才会被调用。继承APIView的视图类默认不会自动完成对象获取与权限校验的绑定,因此需要通过以下两种方式修复:

方案1:改用GenericAPIView子类(推荐)

GenericAPIView及其子类(如RetrieveAPIView、DestroyAPIView)内置了get_object()方法,该方法会自动调用check_object_permissions(request, obj),从而触发has_object_permission校验。

示例代码:

from rest_framework.generics import RetrieveDestroyAPIView
from .models import YourModel
from .permissions import CustomAccessPermission
from .serializers import YourModelSerializer

class MyView(RetrieveDestroyAPIView):
    permission_classes = [CustomAccessPermission]
    queryset = YourModel.objects.all()  # 替换为你的数据模型
    serializer_class = YourModelSerializer  # 替换为你的序列化器

    # 如需自定义对象获取逻辑,可重写get_object方法
    # def get_object(self):
    #     obj = super().get_object()
    #     # 额外逻辑
    #     return obj

方案2:在APIView中手动触发权限校验

若坚持使用APIView,需在get/delete方法中手动获取对象,并调用check_object_permissions触发权限校验。

示例代码:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import YourModel
from .permissions import CustomAccessPermission
from .serializers import YourModelSerializer

class MyView(APIView):
    permission_classes = [CustomAccessPermission]

    def get(self, request, pk):
        try:
            obj = YourModel.objects.get(pk=pk)
        except YourModel.DoesNotExist:
            return Response({"detail": "对象不存在"}, status=status.HTTP_404_NOT_FOUND)
        
        # 手动触发对象权限校验
        self.check_object_permissions(request, obj)
        
        serializer = YourModelSerializer(obj)
        return Response(serializer.data)

    def delete(self, request, pk):
        try:
            obj = YourModel.objects.get(pk=pk)
        except YourModel.DoesNotExist:
            return Response({"detail": "对象不存在"}, status=status.HTTP_404_NOT_FOUND)
        
        # 手动触发对象权限校验
        self.check_object_permissions(request, obj)
        
        obj.delete()
        return Response({"detail": "删除成功"}, status=status.HTTP_204_NO_CONTENT)

确保自定义权限类实现正确

确认你的CustomAccessPermission类逻辑无误,建议增加用户认证校验:

from rest_framework import permissions

class CustomAccessPermission(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        # 先校验用户是否已登录
        if not request.user.is_authenticated:
            return False
        # 校验用户是否为对象创建者
        return obj.user_id == request.user.id

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 00:20:00