Django REST Framework用@permission_classes装饰器替代类属性不生效如何解决
问题原因
@permission_classes是DRF专门为**函数视图(FBV)**设计的装饰器,不适用于类视图(CBV)的实例方法。
类视图的权限校验逻辑执行时机早于请求分发到具体HTTP方法(get/post等)的步骤,校验阶段只会读取类级别定义的permission_classes属性,等到进入get方法执行时,权限校验流程已经结束,此时给方法加的权限装饰器不会被触发,因此身份校验失效。
另外你使用装饰器的参数格式也存在问题:permission_classes接收的是权限类组成的可迭代对象(列表/元组),不能直接传单个权限类作为参数。
解决方法
根据你的需求,可选以下两种方案实现不声明类属性的权限控制:
方案1:重写get_permissions方法(支持单方法权限配置)
重写类视图的get_permissions方法,根据请求方法动态返回对应的权限类,可实现不同HTTP方法使用不同权限规则的需求:
class some_random_api(generics.GenericAPIView): def get_permissions(self): # 仅GET方法需要登录校验 if self.request.method == 'GET': return [IsAuthenticated()] # 其他方法沿用父类逻辑,可按需自定义 return super().get_permissions() def get(self,request): return HttpResponse("You call random test api")
方案2:使用类装饰器给整个类配置权限
将@permission_classes装饰器直接加在类上,装饰器会自动给类注入permission_classes属性,效果和直接声明类属性一致:
from rest_framework.decorators import permission_classes # 注意参数要包为元组/列表,末尾逗号不能省略 @permission_classes((IsAuthenticated, )) class some_random_api(generics.GenericAPIView): def get(self,request): return HttpResponse("You call random test api")
内容的提问来源于stack exchange,提问作者Chau Loi
相关产品推荐
相关产品推荐

