You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:10:54