如何在DjangoRestFramework ViewSet自定义方法中使用permission_classes?
在Django Rest Framework ViewSet自定义方法中设置permission_classes
你直接在方法内部定义permission_classes局部变量的方式不生效,因为DRF的权限检查机制只会读取类级别的permission_classes属性,或者通过get_permissions()钩子方法返回的权限实例。以下是针对不同场景的解决方案:
场景1:为默认动作(如create/list/retrieve)单独设置权限
如果你的方法是ViewSet默认支持的动作(比如代码里的create),可以重写get_permissions()方法,根据当前动作动态返回权限:
from rest_framework.viewsets import GenericViewSet from rest_framework.permissions import IsAuthenticated, IsAdminUser from rest_framework.response import Response class UserViewset(GenericViewSet): permission_classes = (IsAuthenticated,) # 默认权限 def get_permissions(self): # 针对create动作使用管理员权限 if self.action == 'create': return [IsAuthenticated(), IsAdminUser()] # 其他动作沿用默认权限 return super().get_permissions() def create(self, request, *args, **kwargs): # 你的业务逻辑实现 return Response({"status": "success", "message": "创建用户成功"})
场景2:为自定义非默认动作方法设置权限
如果是你自己新增的方法(非create/list这类默认动作),需要先用@action装饰器将其注册为API端点,然后直接在装饰器中指定permission_classes:
from rest_framework.decorators import action class UserViewset(GenericViewSet): permission_classes = (IsAuthenticated,) @action(detail=False, methods=['post'], permission_classes=[IsAuthenticated, IsAdminUser]) def admin_operation(self, request): # 仅管理员可访问的自定义方法逻辑 return Response({"message": "管理员专属操作"})
关键说明
get_permissions()方法返回的是权限类的实例列表,而非类本身,所以要写成IsAuthenticated()而不是IsAuthenticated。- 只有通过
@action装饰或ViewSet默认支持的动作,才会被DRF的路由系统识别为API端点,普通未装饰的方法无法直接通过HTTP请求访问。
内容的提问来源于stack exchange,提问作者Khubaib Khawar
相关产品推荐
相关产品推荐

