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

Django中如何将MeasurememtResult关联对象合并为嵌套列表?

解决Django中prefetch_related关联对象合并为列表的问题

嘿,我看你现在遇到的问题是用prefetch_related获取关联数据后,返回的是重复的主表数据,而不是期望的主表嵌套关联列表的结构。这主要是因为你在queryset里用了values()方法,它会把关联表的字段和主表字段平铺,导致每条关联记录对应一条主表数据,自然就重复了。下面给你一步步的解决方案:

第一步:修正QuerySet,移除values()

首先要去掉values(),直接获取DeviceMeasurement的对象实例,prefetch_related('res_data')会帮你提前加载所有关联的MeasurememtResult数据,同时避免N+1查询的性能问题。修改后的views.py如下:

class GetMeasurements(viewsets.GenericViewSet, mixins.ListModelMixin):
    permission_classes = (IsAuthenticated,)
    serializer_class = GetMeasurementsSerializer
    # 直接获取对象实例,用prefetch_related预加载关联数据
    queryset = DeviceMeasurement.objects.prefetch_related('res_data').all()

第二步:构建嵌套序列化器

接下来需要定义一个子序列化器处理MeasurememtResult的数据,然后在主序列化器里用这个子序列化器生成关联数据的列表。修改serializers.py:

# 先定义关联表的子序列化器
class MeasurementResultSerializer(serializers.ModelSerializer):
    class Meta:
        model = MeasurememtResult
        fields = ('measurement_result', 'measurement_type')

# 主序列化器
class GetMeasurementsSerializer(serializers.ModelSerializer):
    # 用子序列化器嵌套关联数据,many=True表示这是一个列表
    res_data = MeasurementResultSerializer(many=True, source='res_data')
    patient__first_name = serializers.CharField(source='patient.first_name')
    device__id = serializers.IntegerField(source='device.id')

    class Meta:
        model = DeviceMeasurement
        fields = ('created_date', 'front_id', 'patient__first_name', 'device__id', 'res_data')

这里解释几个关键细节:

  • source='res_data'指定序列化器要读取DeviceMeasurement实例的res_data属性(也就是你在模型里定义的related_name)
  • patient__first_name和device__id通过source关联主表的外键字段,替代之前values()里的扁平写法
  • many=True告诉序列化器这是一个集合数据,会自动把所有关联的MeasurememtResult整合成数组

第三步:验证返回结构

现在你的接口返回结果就会和你期望的一致了,示例如下:

{
    "created_date": "2020-06-05T15:03:22.481032+03:00",
    "front_id": null,
    "patient__first_name": "Alex",
    "device__id": 8,
    "res_data": [
        {"measurement_result": 120.0, "measurement_type": "blood_pressure_DIA"},
        {"measurement_result": 100.0, "measurement_type": "blood_pressure_SYS"}
    ]
}

另外提个小细节:你的模型MeasurememtResult拼写少了一个'e'(正确应为MeasurementResult),如果是笔误的话建议修正,避免后续开发中出现不必要的拼写错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 09:52:51