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

如何在Django REST Framework序列化器中正确展示带中间表的ManyToMany字段

错误原因

你使用through参数自定义多对多关联的中间表后,SalesAction模型的medicines字段默认返回的是关联的Medicine模型实例集合,并不是中间表SalesActionMedicine的实例集合。你将中间表对应的序列化器直接绑定在medicines字段上时,序列化器会尝试用中间表的字段(如sales_action)去匹配Medicine实例的属性,自然就抛出属性不存在的错误。

解决方案

方案1:需要返回中间表的额外字段(数量类型、数量)

这是符合你需求的常用方案,修改序列化器如下:

  1. 优化中间表序列化器,可嵌套序列化药品基础信息,同时去掉冗余的sales_action字段
class SalesActionMedicineSerializer(serializers.ModelSerializer):
    # 嵌套序列化药品详情,按需配置需要返回的药品字段
    class MedicineSerializer(serializers.ModelSerializer):
        class Meta:
            model = Medicine
            fields = ('id', 'name') # 可自行添加药品的其他字段

    medicine = MedicineSerializer(read_only=True)
    class Meta:
        model = SalesActionMedicine
        fields = ('medicine', 'quantity_type', 'quantity')
  1. 修改SalesAction序列化器,通过source指定获取中间表的反向关联数据
class SalesActionSerializer(serializers.ModelSerializer):
    # source指定为中间表的默认反向关联名,默认规则是中间表名小写+_set
    medicines = SalesActionMedicineSerializer(source='salesactionmedicine_set', many=True, read_only=True)

    class Meta:
        model = SalesAction
        fields = ('sales_representative', 'doctor', 'remark', 'date', 'medicines')

方案2:仅需要返回药品基础信息,不需要中间表字段

如果不需要数量等中间表字段,直接给medicines绑定药品序列化器即可:

class MedicineSerializer(serializers.ModelSerializer):
    class Meta:
        model = Medicine
        fields = ('id', 'name') # 按需配置字段

class SalesActionSerializer(serializers.ModelSerializer):
    medicines = MedicineSerializer(many=True, read_only=True)

    class Meta:
        model = SalesAction
        fields = ('sales_representative', 'doctor', 'remark', 'date', 'medicines')
性能优化提示
  • 查询SalesAction数据时建议使用prefetch_related预加载关联数据,避免N+1查询问题,示例:
queryset = SalesAction.objects.prefetch_related('salesactionmedicine_set__medicine').all()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 07:36:06