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
相关产品推荐
相关产品推荐

