【问题标题】:Django Rest Framework nested object serialization, depth >= 2Django Rest Framework 嵌套对象序列化,深度 >= 2
【发布时间】:2026-02-20 09:05:01
【问题描述】:

我正在使用 Django Rest Framework 构建 API。我想发布一个 takeoutOrder JSON 对象,如下所示:

{
    "takeoutOrderID": "001",
    "components": [
        {
            "name": "chicken",
            "componentID": 1
        },
        {
            "name": "beef",
            "componentID": 2
        },
        {
            "name": "rice",
            "componentID": 3
        },
        {
            "name": "carrot",
            "componentID": 4
        }
    ],
    "meals": [
        {
            "name": "chickenAndRice",
            "mealID": 00,
            "components": [1,3]
        },
        {
            "name": "kitchenSink",
            "mealID": 01,
            "components": [1,2,3,4]
        }
    ]
}

我的模型如下所示:

class TakeoutOrder(models.Model):
    requestID = models.CharField(max_length=100, primary_key=True)

    def get_absolute_url(self):
        return "/api/request/%s/" % self.requestID


class Meal(models.Model):
    name = models.CharField(max_length=100, blank=True, default='')
    mealID = models.CharField(max_length=100, primary_key=True)
    takeoutOrder = models.ForeignKey(TakeoutOrder, related_name="meals")


class Component(models.Model):
    name = models.CharField(max_length=100)
    componentID = models.CharField(max_length=100, primary_key=True)
    takeoutOrder = models.ForeignKey(TakeoutOrder, related_name='components')
    meal = models.ForeignKey(Meal, related_name='components', null=True)

我的序列化器如下所示:

class ComponentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Component
        fields = ('name', 'componentID')

class MealSerializer(serializers.ModelSerializer):
    components = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
    class Meta:
        model = Meal
        fields = ('name', 'mealID', 'components')

class TakeoutOrderSerializer(serializers.ModelSerializer):
    components = ComponentSerializer(many=True)
    meals = MealSerializer(many=True)

    class Meta:
        model = TakeoutOrder
        fields = ('takeoutOrderID', 'components', 'meals')

    def create(self, validated_data):
        components_data = validated_data.pop('components')
        meals_data = validated_data.pop('meals')
        takeoutOrder = TakeoutOrder.objects.create(**validated_data)

        for meal_data in meals_data:
            Meal.objects.create(takeoutOrder=takeoutOrder, **meal_data)

        for component_data in components_data:
            Component.objects.create(takeoutOrder=takeoutOrder, **component_data)

        return takeoutOrder

当我尝试使用此设置发布到 /takeoutOrder 端点时,我成功创建了一个对象,但是餐点的组件数组为空(我相信这是因为组件尚未创建餐点时创建)。关于如何更好地编写我的序列化 create() 方法的任何想法或任何其他建议?我有点卡住了。

如果有其他帖子回答这个问题,请提前道歉,我找了一会儿,但找不到。

谢谢!!

【问题讨论】:

  • 您想复制数据库中的组件?因为你在每个组件中都存储了肉的主键。
  • 我的模型可能不正确,但我正在尝试将组件的主键链接到它们所属的每餐。序列化过程需要验证,事实上,为这顿饭列出的每个组件都存在。

标签: python django django-models django-rest-framework django-serializer


【解决方案1】:

首先:我认为模型是错误的。

因为:您将创建多个组件,因为您只需要一个关联。

更改模型组件

class Component(models.Model):
    name = models.CharField(max_length=100)
    componentID = models.CharField(max_length=100, primary_key=True)

添加一个新的模型

class MealComponent(models.Model):
    meal = models.ForeignKey(Meal)
    component = models.ForeignKey(Component)

然后:

def create(self, validated_data):
    components_data = validated_data.pop('components')
    meals_data = validated_data.pop('meals')
    takeoutOrder = TakeoutOrder.objects.create(**validated_data)

    for component_data in components_data:
        Component.objects.create(**component_data)

    for meal_data in meals_data:
        meal_data.update({'takeoutOrder':takeoutOrder}
        meal = Meal.objects.create(**meal_data)
        meal_components = meal_data.pop('components')

        for meal_comp in meal_components:
            component = Component.objects.get(pk=meal_comp)
            MealComponent.objects.create(meal=meal,component=component)

    return takeoutOrder

【讨论】:

  • 感谢您的建议。不幸的是,我刚刚尝试了您的实现,但我仍然在响应中的 meals 中得到空的 components[] 数组。组件似乎还没有存储到数据库中。
  • 我更新了答案,为了澄清答案,也许现在,可以解决这个问题。
  • 差不多就是这样,@PauloPessoa。感谢您的帮助!我将使用对我有用的稍微修改的解决方案来跟进这篇文章,但做得很好!