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

Django REST ModelViewSet执行PATCH后返回404问题求助

问题分析与解决方案

核心问题

  1. 错误使用@action装饰器:你给get_queryset方法添加了@action(detail=True, methods=['patch'])装饰器,这个装饰器是用来定义自定义API端点的,而get_queryset是ModelViewSet的核心方法,负责提供查询集,这种用法会导致你的get_queryset没有覆盖视图的默认逻辑,反而变成了一个无关的API接口(路径为/documents/<pk>/get_queryset/)。

  2. 详情视图过滤导致对象找不到:当你对/documents/2/发送PATCH请求时,请求没有携带is_live参数,此时你的get_queryset会返回is_live=True的对象集合,但你要修改的对象此时is_live还是false(你正准备通过这个请求把它改成true),所以对象不在查询集内,最终导致get_object()找不到对象,返回404错误。


修复步骤

1. 移除get_queryset上的错误装饰器

删除@action(detail=True, methods=['patch'])这一行,让get_queryset正确覆盖ModelViewSet的方法。

2. 区分列表与详情视图的查询集逻辑

修改get_queryset,让列表视图按is_live参数过滤,详情视图(更新、查看单个对象等)返回所有对象,确保任何状态的文档都能被修改:

def get_queryset(self):
    # 获取基础查询集
    queryset = super().get_queryset()
    
    # 仅对列表视图应用is_live过滤规则
    if self.action == 'list':
        is_live_param = self.request.query_params.get('is_live')
        if is_live_param is not None:
            # 处理字符串形式的布尔参数(如'false'转成False)
            is_live = is_live_param.lower() != 'false'
            queryset = queryset.filter(is_live=is_live)
        else:
            # 默认返回live状态的文档
            queryset = queryset.filter(is_live=True)
    
    # 详情视图返回所有对象,确保能修改任意状态的文档
    return queryset

3. 结合FilterSet简化逻辑(可选)

你已经定义了DocumentFilter,可以利用它简化过滤逻辑,无需手动处理is_live参数:

def get_queryset(self):
    queryset = super().get_queryset()
    
    if self.action == 'list':
        # 默认返回live文档,有is_live参数时由FilterSet自动处理
        if 'is_live' not in self.request.query_params:
            queryset = queryset.filter(is_live=True)
    
    return queryset

4. 移除不必要的update方法修改(可选)

你的update方法强制设置kwargs['partial'] = True,会导致PUT请求也变成部分更新,若不需要这个行为,可以删除该方法,使用ModelViewSet默认的update和partial_update逻辑。


验证效果

  • 访问/documents/?is_live=false可获取所有非live的文档列表
  • 对任意文档发送PATCH请求(如/documents/2/),即使将is_live改为true,也能成功找到对象并完成更新
  • 更新后的文档会从/?is_live=false列表中消失,出现在默认的/documents/列表中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 02:49:58