Вложенное представление сериализатора для 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']