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

Django DRF多对多关联场景下序列化器id字段丢失问题咨询

问题原因
  1. DRF的ModelSerializer默认将模型主键id字段设置为只读字段,反序列化(将请求JSON转换为validated_data)时会自动过滤只读字段,所以你拿到的lines数据里没有id。
  2. 你使用的PriceLineSerializerTest没有显式声明id字段为可写字段,因此默认遵循只读规则,反序列化时直接丢弃了传入的id值。
解决方案

第一步:修改嵌套的PriceLine序列化器

显式声明id字段允许读写:

class PriceLineSerializerTest(serializers.ModelSerializer):
    # 显式声明id字段,允许反序列化时接收传入值
    id = serializers.IntegerField(required=False)
    class Meta:
        model = PriceLine
        fields = ['id', 'price', 'product']

第二步:补全PriceTableSerializer的update逻辑

class PriceTableSerializer(serializers.ModelSerializer):
    """
    PriceTableSerializer
    """
    lines = PriceLineSerializerTest(many=True)
    class Meta:
        model = PriceTable
        exclude = ['standard', 'client',]
        
    def update(self, instance, validated_data):
        instance.name = validated_data.get('name', instance.name)
        instance.save()
        lines_data = validated_data.get('lines', [])
        # 存储处理后的PriceLine实例,用于后续更新多对多关联
        processed_lines = []
        
        for line_data in lines_data:
            line_id = line_data.get('id')
            if line_id:
                # 已有id则更新对应PriceLine
                try:
                    line = PriceLine.objects.get(id=line_id)
                    line.price = line_data.get('price', line.price)
                    line.product = line_data.get('product', line.product)
                    line.save()
                    processed_lines.append(line)
                except PriceLine.DoesNotExist:
                    # 可根据业务需求决定抛出异常或者创建新条目
                    raise serializers.ValidationError(f"价目条目id={line_id}不存在")
            else:
                # 没有id则创建新的PriceLine
                new_line = PriceLine.objects.create(**line_data)
                processed_lines.append(new_line)
        
        # 更新多对多关联,替换原有关联关系
        instance.lines.set(processed_lines)
        return instance
注意事项
  • 如果业务不允许在更新价目表时新增PriceLine,可删除创建新条目的逻辑,对无id的传入数据直接抛校验错误
  • PATCH请求如果未传入lines字段,不会修改原有价目条目关联,符合局部更新的语义
  • 可根据需求添加事务控制,避免更新一半失败导致数据不一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 01:27:01