Вложенное представление сериализатора для PrimaryKeyRelatedField

Я хочу добавлять и удалять продукты в order, используя только их идентификаторы, но я хочу, чтобы представление order выглядело как вложенный сериализатор.

Мои модели:

class Product(models.Model):
    title = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=1_000, decimal_places=2)

    def __str__(self):
        return self.title

class Order(models.Model):
    date = models.DateField()
    products = models.ManyToManyField(Product, blank=True, related_name='orders')

Мои сериализаторы:

class ProductSerializer(serializers.ModelSerializer):
    price = serializers.DecimalField(max_digits=1_000,
                                     decimal_places=2,
                                     coerce_to_string=False)

    class Meta:
        model = Product
        fields = ['id', 'title', 'price']


class OrderSerializer(serializers.ModelSerializer):
    products = serializers.PrimaryKeyRelatedField(queryset=Product.objects.all(), many=True)

    class Meta:
        model = Order
        fields = ['id', 'date', 'products']

Я пытаюсь получить следующее представление:

{
    "id": 1,
    "date": "2021-08-12",
    "products": [
        {
            "id": 1,
            "title": "Item 1",
            "price": 19.99
        },
        {
            "id": 3,
            "title": "Item 3",
            "price": 49.99
        }
    ]
}

Однако, если я хочу создать вышеуказанное order, то json должен выглядеть следующим образом:

{
    "date": "2021-08-12",
    "products":[1, 3]
}

А если я хочу добавить товар с id==2 к вышеуказанному order, то это должно выглядеть следующим образом:

{
    "id": 1,
    "date": "2021-08-12",
    "products":[1, 3, 2]
}

Я пробовал переопределить метод to_representation() и добавить туда вложенный сериализатор, но я понятия не имею, как это сделать. Должно ли это выглядеть примерно так, или я иду в совершенно неверном направлении?

def to_representation(self, instance):
    data = super().to_representation(instance)
    data['products'] = ProductSerializer(data=instance['products'])
    return data

В итоге я исправил это с помощью метода to_representation(). Не знаю, лучший ли это способ, но пока работает.

def to_representation(self, instance):
    data = super().to_representation(instance)
    products_list = []
    for product_id in data['products']:
        product = instance.products.get(pk=product_id)
        products_list.append(
            {
                'id': product.id,
                'title': product.title,
                'price': product.price
            }
        )
    data['products'] = products_list
    return data

используйте вложенные отношения сериализатора.
и ваш класс сериализатора OrderSerializer будет выглядеть следующим образом:

class OrderSerializer(serializers.ModelSerializer):
    products = ProductSerializer(many=True)

    class Meta:
        model = Order
        fields = ['id', 'date', 'products']
Вернуться на верх