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

Django REST框架PUT/PATCH请求更新失败反而新建对象问题排查

问题核心原因

你遇到的更新时新建Product对象的问题,本质是作为主键的sku字段被修改触发了Django ORM的新建逻辑:
Django ORM的save()方法默认逻辑为:如果传入的实例对象主键值发生变更,会将当前数据作为全新的对象插入数据库,而非更新原有主键对应的记录。

结合你的代码场景,触发条件为:
你发起PUT/PATCH更新请求时,请求体中携带了sku字段,且该字段值和请求URL中传入的主键pk值不一致。序列化器在校验时会接收请求传入的sku值,覆盖原有实例的sku属性,调用save()时就会生成新的对象。

排查步骤
  • 先抓包查看你发起更新请求的请求体内容,确认是否携带了sku字段,且值和请求URL路径中的pk值不匹配
  • 确认序列化器是否开放了sku字段的可写权限,你的现有代码把sku放在了普通fields列表中,默认是可写的,允许用户通过接口修改主键
解决方法

绝大多数业务场景下商品SKU作为唯一标识不会允许随意修改,最优解决方案是将sku字段设为序列化器只读字段:
修改ProductSerializer代码如下:

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = [
            "sku",
            "product_name",
            "product_price",
            "product_brand",
            "times_searched_anonymous"
        ]
        # 新增以下配置,sku设为只读,不允许通过接口修改
        read_only_fields = ["sku"]

如果你确实有修改SKU的特殊需求,需要单独写逻辑:先删除原有SKU对应的记录,再用新的SKU值创建新对象,不推荐直接依赖默认save逻辑实现SKU修改。

另外补充两个你代码中的小问题,避免后续出其他异常:

  • put方法中return Response(serializer.data)前存在缩进错误,需要和上层if判断对齐
  • patch方法更新成功后返回状态码201不符合REST规范,201是资源创建成功的状态码,更新成功应该返回200

内容的提问来源于stack exchange,提问作者Valter Núñez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:45:04