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

如何在Django REST Framework序列化器中实现自定义嵌套数据结构

问题背景

现有客户端采用如下结构发送数据:

{
    "hive_metadata": {"name": "hive name"},
    "bees": [{"name": "bee 1"}, {"name": "bee 2"}, ...]
}

对应的Django模型定义:

class Hive(models.Model):
    name = models.CharField(max_length=32, help_text="name")


class Bee(models.Model):
    name = models.CharField(max_length=32, help_text="name")
    hive = models.ForeignKey(
        Hive, help_text="The Hive associated with this Bee", on_delete=models.CASCADE
    )

当前通过手动遍历解析数据,希望改用Django REST Framework序列化器重构,但嵌套的hive_metadata字段实现遇到阻碍。已实现能生成不含hive_metadata结构的序列化器:

class BeesSerializer(ModelSerializer):
    class Meta:
        model = models.Bee
        fields = ("name",)

class PopulatedHiveSerializer(ModelSerializer):
    bees = BeesSerializer(many=True, source="bee_set")
    class Meta:
        model = models.Hive
        fields = ("name","bees",)

该序列化器输出结构:

{
    "name": "hive name",
    "bees": [{"name": "bee 1"}, {"name": "bee 2"}, ...]
}

尝试通过子序列化器实现嵌套的hive_metadata,但无法确定source参数值以将同一对象传入内层序列化器:

class HiveMetaDataSerializer(ModelSerializer):
    class Meta:
        model = models.Hive
        fields = ("name",)

class PopulatedHiveSerializer(ModelSerializer):
    bees = BeesSerializer(many=True, source="bee_set")
    hive_metadata = HiveMetaDataSerializer(source=???)
    class Meta:
        model = models.Hive
        fields = ("hive_metadata","bees",)

请问能否通过Django REST Framework序列化器实现该需求?


解决方案

完全可以实现,只需要将source参数设为self即可,它表示把当前序列化的Hive对象本身传入HiveMetaDataSerializer中。

修改后的序列化器代码如下:

class HiveMetaDataSerializer(ModelSerializer):
    class Meta:
        model = models.Hive
        fields = ("name",)

class PopulatedHiveSerializer(ModelSerializer):
    bees = BeesSerializer(many=True, source="bee_set")
    # 使用source='self'将当前Hive对象传入子序列化器
    hive_metadata = HiveMetaDataSerializer(source='self')
    class Meta:
        model = models.Hive
        fields = ("hive_metadata","bees",)

这样序列化后就能得到客户端需要的结构:

{
    "hive_metadata": {"name": "hive name"},
    "bees": [{"name": "bee 1"}, {"name": "bee 2"}, ...]
}

如果需要支持反序列化(解析客户端传入的数据),还需要在序列化器中添加create方法来处理嵌套数据的保存逻辑,示例如下:

class PopulatedHiveSerializer(ModelSerializer):
    bees = BeesSerializer(many=True)
    hive_metadata = HiveMetaDataSerializer(source='self')

    class Meta:
        model = models.Hive
        fields = ("hive_metadata", "bees")

    def create(self, validated_data):
        # 提取bees数据
        bees_data = validated_data.pop('bees')
        # 创建Hive实例
        hive = Hive.objects.create(**validated_data['hive_metadata'])
        # 创建关联的Bee实例
        for bee_data in bees_data:
            Bee.objects.create(hive=hive, **bee_data)
        return hive

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 21:13:29