能否在基于类的视图(CBV)中为每个方法单独设置权限类?
在Django REST Framework的类视图(CBV)中为不同方法单独设置权限
完全可以在DRF的类视图(CBV)中为每个HTTP方法单独配置权限,不需要切换到函数视图。下面是两种常用的实现方式:
方式一:重写get_permissions方法(推荐)
这是DRF官方推荐的做法,通过重写视图类的get_permissions方法,根据当前请求的HTTP方法返回对应的权限实例列表:
from rest_framework.permissions import AllowAny, IsAuthenticated from rest_framework.views import APIView from rest_framework import status from rest_framework.response import Response class ExampleListAPIView(APIView): def get_permissions(self): # 根据请求方法分配对应权限 if self.request.method == 'GET': return [AllowAny()] elif self.request.method == 'POST': return [IsAuthenticated()] # 其他方法默认继承父类的权限配置(如果有的话) return super().get_permissions() def get(self, request): examples = Example.objects.all() serializer = ExampleListSerializer(examples, many=True) return Response(serializer.data, status=status.HTTP_200_OK) def post(self, request): serializer = ExampleListSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
这种方式完全遵循DRF的权限处理流程,能和框架的权限错误处理、文档生成等功能无缝集成,代码结构也更清晰。
方式二:在方法内手动检查权限
如果你需要更灵活的权限控制逻辑,也可以在具体的视图方法内手动实例化权限类并检查权限:
from rest_framework.permissions import AllowAny, IsAuthenticated from rest_framework.views import APIView from rest_framework import status from rest_framework.response import Response from rest_framework.exceptions import PermissionDenied class ExampleListAPIView(APIView): def get(self, request): # 手动验证GET请求的权限 permission = AllowAny() if not permission.has_permission(request, self): raise PermissionDenied() examples = Example.objects.all() serializer = ExampleListSerializer(examples, many=True) return Response(serializer.data, status=status.HTTP_200_OK) def post(self, request): # 手动验证POST请求的权限 permission = IsAuthenticated() if not permission.has_permission(request, self): raise PermissionDenied() serializer = ExampleListSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
不过这种方式需要手动抛出权限异常,不如重写get_permissions方法优雅,一般只在特殊场景下使用。
内容的提问来源于stack exchange,提问作者lezaf
相关产品推荐
相关产品推荐

