Django路由权限配置报错:'list' object is not callable 求助
解决Django REST Framework中'list' object is not callable错误
错误原因分析
你遇到的这个错误,根源在于ViewSet的action方法上错误混用了@api_view和@permission_classes装饰器,而且装饰器的用法和顺序都有问题:
@api_view是专门用来装饰函数视图的,而ViewSet的action是类视图中的方法,完全不需要这个装饰器。当你在action方法上加了@api_view后,它会改变视图的内部处理逻辑,导致后续的@permission_classes装饰器被错误地识别成了一个列表(而非可调用的装饰器),最终抛出'list' object is not callable的异常。- 另外你还存在方法冲突:
@action指定了methods=["post"],但@api_view(['GET'])又限定了只能处理GET请求,这会导致后续请求方法不匹配的问题。
正确的解决方案
在DRF的ViewSet中,给特定action配置权限的标准方式是直接在@action装饰器中指定permission_classes参数,不需要额外的@api_view或@permission_classes装饰器。修改后的代码如下:
from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.viewsets import GenericViewSet class UserViewSet(GenericViewSet): queryset = User.objects.all() serializer_class = UserSerializer permission_classes = [IsAuthenticated] renderer_classes = [JSONRenderer] @action( url_path="an/api/path", detail=False, methods=["get", "post"], # 统一指定需要支持的请求方法 renderer_classes=[JSONRenderer], permission_classes=[IsAuthenticated] # 在这里覆盖类级别的权限配置 ) def get_stuff(self, request): # 你的业务逻辑代码 return Response({"status": "success", "data": "your stuff here"})
额外说明
如果想要把某个action设为公开访问(不需要认证),只需要把permission_classes参数改成[]或者[AllowAny]即可,比如:
from rest_framework.permissions import AllowAny # ... 省略其他代码 ... @action( url_path="public/path", detail=False, methods=["get"], permission_classes=[AllowAny] # 允许未认证用户访问 ) def public_stuff(self, request): return Response({"message": "This is public content"})
内容的提问来源于stack exchange,提问作者Devin Dixon
相关产品推荐
相关产品推荐

