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

DRF可浏览API访问列表视图触发create权限引发KeyError如何解决

解决方案

方案1:修复权限类逻辑(最推荐,无副作用)

你的IsListItemOwner权限类本身存在健壮性问题:没有处理list_id不存在、对应List对象不存在的场景,就算没有可浏览API的问题,恶意请求也会触发500错误。修改后的权限类代码如下:

from rest_framework import permissions
from rest_framework.exceptions import NotFound

class IsListItemOwner(permissions.BasePermission):
    def has_permission(self, request, view):
        if view.action == "create":
            # 从request.data安全读取list_id,不存在则返回None
            list_id = request.data.get("list_id")
            # 可浏览API渲染表单时无提交数据,直接返回True允许显示表单
            # 真实POST请求如果未传list_id,会被序列化器的required校验拦截,返回400错误
            if not list_id:
                return True
            # 捕获List不存在的异常,返回规范的404错误
            try:
                list_obj = List.objects.get(pk=list_id)
            except List.DoesNotExist:
                raise NotFound("指定的列表不存在")
            return list_obj.user == request.user
        return True

    def has_object_permission(self, request, view, obj):
        return obj.get_root().list.user == request.user

修改后即可正常使用可浏览API,同时补全了权限类的异常处理逻辑,避免恶意请求触发500错误。

方案2:自定义表单渲染逻辑(可选,适合不需要在列表页显示创建表单的场景)

如果你不需要在列表页展示创建表单,可以重写可浏览API渲染器的表单显示判断,直接隐藏列表页的创建表单:

class ListItemViewSet(viewsets.ModelViewSet):
    queryset = ListItem.objects.all()
    # 其余原有逻辑保持不变
    
    def get_renderers(self):
        renderers = super().get_renderers()
        if self.action == "list":
            from rest_framework.renderers import BrowsableAPIRenderer
            # 自定义渲染器,隐藏列表页的POST创建表单
            class NoFormBrowsableAPIRenderer(BrowsableAPIRenderer):
                def show_form_for_method(self, view, method, request, obj):
                    if method == "POST":
                        return False
                    return super().show_form_for_method(view, method, request, obj)
            # 替换原有可浏览API渲染器
            for i, renderer in enumerate(renderers):
                if isinstance(renderer, BrowsableAPIRenderer):
                    renderers[i] = NoFormBrowsableAPIRenderer()
        return renderers

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 10:57:03