Как разместить данные во вложенном сериализаторе с использованием поля id

Я пытаюсь разместить данные во вложенном сериализаторе, используя только поле id, но это не работает.

Этот проект предназначен для выполнения заказов в ресторанах

Что я хочу увидеть

Вот как я передаю данные:

{
    "is_done": false,
    "dishes": [
        {"dish":1}
    ]
}

Запрос GET выглядит следующим образом:

{
    "id": 14,
    "is_done": false,
    "dishes": [
        {
            "dish": 1,
            "quantity": 1
        }
    ]
}

Но я хочу видеть это вот так

{
    "id": 14,
    "is_done": false,
    "dishes": [
        {
            "dish": {
                "id": 1,
                "name": "Simple dish 1",
                "price": "200.00"
            },
            "quantity": 1
        }
    ]
}

Вот мой код на python

OrderItemSerializer
OrderSerializer

class OrderItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderItem
        fields = (
            'dish',
            'quantity',
        )


class OrderSerializer(serializers.ModelSerializer):
    dishes = OrderItemSerializer(many=True, read_only=False)

    class Meta:
        model = Order
        fields = (
            'id',
            'is_done',
            'dishes',
            # 'created_at',
            # 'updated_at',
        )

    def create(self, validated_data):
        order_items = validated_data.pop('dishes')
        order = Order.objects.create(**validated_data)
        for dish in order_items:
            OrderItem.objects.create(order=order, **dish)
        return order
    
    def update(self, instance, validated_data):
        order_items = validated_data.pop('dishes')

        instance.is_done = validated_data.get('is_done', instance.is_done)
        instance.save()

        for dish in order_items:
            order_item = OrderItem.objects.get(order=instance)
            order_item.dish = dish['dish']
            order_item.quantity = dish['quantity']
            order_item.save()

        return instance

Модели

class Order(models.Model):
    is_done = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'Заказ'
        verbose_name_plural = 'Заказы'


class OrderItem(models.Model):
    order = models.ForeignKey(Order, related_name='dishes',
                              on_delete=models.CASCADE)
    dish = models.ForeignKey(Dish, on_delete=models.CASCADE)
    quantity = models.IntegerField(default=1)

вы можете добавить serializer для блюда к вашему OrderItemSerializer, которое представляет данные так, как вы хотите. Таким образом, это будет:

class DishSerializer(serializers.ModelSerializer):
    class Meta:
        model = Dish
        fields = (
            'id',
            'name',
            'price',
        )
class OrderItemSerializer(serializers.ModelSerializer):
    dish = DishSerializer(read_only=True)
    class Meta:
        model = OrderItem
        fields = (
            'dish',
            'quantity',
        )

class OrderSerializer(serializers.ModelSerializer):
    dishes = OrderItemSerializer(many=True, read_only=False)

    class Meta:
        model = Order
        fields = (
            'id',
            'is_done',
            'dishes',
            # 'created_at',
            # 'updated_at',
        )

    def create(self, validated_data):
        order_items = validated_data.pop('dishes')
        order = Order.objects.create(**validated_data)
        for dish in order_items:
            OrderItem.objects.create(order=order, **dish)
        return order
    
    def update(self, instance, validated_data):
        order_items = validated_data.pop('dishes')

        instance.is_done = validated_data.get('is_done', instance.is_done)
        instance.save()

        for dish in order_items:
            order_item = OrderItem.objects.get(order=instance)
            order_item.dish = dish['dish']
            order_item.quantity = dish['quantity']
            order_item.save()

        return instance
Вернуться на верх