You need to enable JavaScript to run this app. Django REST创建订单POST接口id字段期望数字却收到OrderedDict报错解决
优惠活动
大模型
产品
解决方案
定价
更多

Django REST创建订单POST接口id字段期望数字却收到OrderedDict报错解决

Django REST Framework 嵌套序列化关联报错的原因与解决方法

报错根因

代码逻辑断层直接触发ORM类型校验错误:

  • OrderCreateSerializer中嵌套的ShopSerializer完成反序列化校验后,返回普通字段字典结构(即报错中提到的OrderedDict),并非smartphone模型的实例对象
  • 从.set()方法的调用可判断,order与smartphone为多对多关联关系,该方法仅接受已存在的模型实例集合或对应实例的主键值集合作为参数,直接传入字典结构时,ORM会将关联字段的值按主键类型解析,自然抛出“Field 'id' expected a number”的类型不匹配错误。

分场景解决方法

结合“创建订单时直接提交完整智能手机商品数据、无需仅传商品ID关联”的需求,按两类业务场景调整代码:

场景1:提交的商品数据对应库内已存在的商品

此场景无需重复创建商品,仅需将传入的商品字典转换为对应模型实例,再完成关联即可。修改OrderCreateSerializer的create方法:

class OrderCreateSerializer(serializers.ModelSerializer):
    smartphone = ShopSerializer(many=True)
    class Meta:
        model = order
        fields = '__all__'

    def create(self, validated_data):
        # 取出校验通过的嵌套商品数据
        smartphone_data_list = validated_data.pop('smartphone')
        # 先创建订单主记录
        order_instance = order.objects.create(**validated_data)
        
        # 根据传入的商品ID匹配真实存在的模型实例
        smartphone_instances = []
        for item in smartphone_data_list:
            # 匹配不到商品时可增加判空逻辑,避免抛出不存在异常
            sp_obj = smartphone.objects.get(id=item['id'])
            smartphone_instances.append(sp_obj)
        
        # 用真实模型实例完成多对多关联
        order_instance.smartphone.set(smartphone_instances)
        return order_instance
  • 若仅需匹配商品、不需要对完整商品字段做入参校验,可给ShopSerializer增加read_only=True配置,减少不必要的校验逻辑。

场景2:提交的商品为全新数据,需随订单同步入库

此场景需先将每一组商品字典写入数据库生成对应实例,再完成订单关联,调整create逻辑如下:

class OrderCreateSerializer(serializers.ModelSerializer):
    smartphone = ShopSerializer(many=True)
    class Meta:
        model = order
        fields = '__all__'

    def create(self, validated_data):
        smartphone_data_list = validated_data.pop('smartphone')
        order_instance = order.objects.create(**validated_data)
        
        smartphone_instances = []
        for item in smartphone_data_list:
            # 逐组校验商品数据并生成新的smartphone实例
            sp_serializer = ShopSerializer(data=item)
            sp_serializer.is_valid(raise_exception=True)
            sp_obj = sp_serializer.save()
            smartphone_instances.append(sp_obj)
        
        order_instance.smartphone.set(smartphone_instances)
        return order_instance
  • 额外提示:当前ShopSerializer中的img1~img6为SerializerMethodField,这类字段默认只读,反序列化阶段不会接收入参、也不会写入校验结果,如果走新建商品逻辑,需要单独为这些图片字段配置可写的文件类型字段,否则传入的图片数据会被自动忽略。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.04 06:36:04