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

Django REST Framework自定义权限方法多次重复调用问题排查

问题描述

开发简易博客应用时编写了自定义权限类,用于限制仅帖子所有者可更新或删除对应帖子。添加print语句校验权限运行状态时,发现每次请求访问对应视图,该权限方法会被调用6次,相关实现代码如下:

class PostUpdateDeletePermission(IsAuthenticated):
    def has_object_permission(self, request, view, obj):
        print("called")
        if request.user.is_superuser:
            return True
        if (request.method == 'PUT' or request.method == 'DELETE') and request.user != obj.user:
            return False
        return True

class PostView(ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = (PostUpdateDeletePermission,)

    def create(self, request): 
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        obj = serializer.save(user=request.user)
        if request.data.get('files_length'):
            PostFile.objects.bulk_create([PostFile(img = request.data.get(f"file-{x}"), post=obj) for x in range(request.data.get('files_length'))])
        return Response({'posts' : serializer.data}, status=201)

刷新DRF可浏览API页面时,控制台累计打印6次called日志,需要定位重复调用原因并给出解决方案。

重复调用原因
  • 最主要的触发源是DRF自带的可浏览API渲染器(BrowsableAPIRenderer)。它在生成页面时,除了校验当前主请求的权限,还会逐个校验该接口支持的所有HTTP动作(PUT、PATCH、DELETE、POST、OPTIONS等)的权限,用来判断是否要在页面上渲染对应操作按钮、提交表单。每一次动作校验只要涉及对象级权限判断,就会触发一次has_object_permission方法。
  • 其次ModelViewSet的list动作默认会对返回结果中的每一个帖子对象,单独执行一次对象级权限校验。如果当前列表页返回了多条Post数据,对应会触发多次方法调用,和可浏览API渲染触发的校验累加后,就会出现你看到的6次打印。
  • 这个重复调用是可浏览API场景下的正常行为,不会出现在普通JSON接口请求中,也不代表你的权限逻辑本身有错误。
解决方案
  • 生产环境不需要特殊处理,只需要在DRF配置中关闭可浏览API,仅保留JSON渲染器即可,多余的权限校验调用会自动消失,配置参考:
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
    ]
}
  • 开发阶段如果觉得多余的打印影响调试,可以调整日志输出规则:在print语句前增加请求方法过滤,只打印PUT、DELETE这类你需要调试的写操作的校验记录,过滤掉GET、OPTIONS等可浏览API渲染触发的无关调用。
  • 如果列表接口本身已经通过过滤queryset保证了返回数据的权限(比如只返回当前用户有权限访问的帖子),可以重写list动作逻辑,跳过逐对象的权限校验,减少不必要的性能损耗,但注意不要影响retrieve、update、destroy这类单对象操作的权限校验逻辑。
  • 不要为了消除重复调用修改权限类的核心判断规则,你当前写的所有者校验逻辑本身是正确的,重复调用只是渲染层的额外触发,不会导致权限绕过问题。

内容的提问来源于stack exchange,提问作者mohamed naser

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:15:44