I am writing an api's application where Order is an entity that provides information about what customers want to buy, one Order can contain different products with different quantity and different prices. The entity that includes this information in Order is called Order Detail.
And I have some problems with double nested serializers.
After post request with:
{
"external_id": "PR-123-321-123",
"details": [{
"product": {"id": 4},
"amount": 10,
"price": "12.00"
}, ... ]
}
I want to get this response:
{
"id": 1,
"status": "new",
"created_at": "2021-01-01T00:00:00",
"external_id": "PR-123-321-123",
"details": [{
"id": 1,
"product": {"id": 4, "name": "Dropbox"},
"amount": 10,
"price": "12.00"
}, ... ]
}
But now i have some error: "Cannot assign "OrderedDict()": "OrderDetail.product" must be a "Product" instance."
What's wrong?
Models:
from django.db import models
class Order(models.Model):
STATUS_CHOICES = (
('new', 'new'),
('accepted', 'accepted'),
('failed', 'failed')
)
status = models.CharField(max_length=12, choices=STATUS_CHOICES, default='new')
created_at = models.DateTimeField(auto_now_add=True)
external_id = models.CharField(max_length=128, unique=True)
class Product(models.Model):
name = models.CharField(max_length=64)
def __str__(self):
return self.name
class OrderDetail(models.Model):
order = models.ForeignKey(Order, related_name='details', on_delete=models.CASCADE)
amount = models.IntegerField()
product = models.ForeignKey(Product, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=8, decimal_places=2)
def __str__(self):
return f'{self.order} detail'
Serializers:
from rest_framework import serializers
from rest_framework.serializers import ModelSerializer
from order.models import Order, Product, OrderDetail
class ProductSerializer(ModelSerializer):
class Meta:
model = Product
fields = '__all__'
read_only_fields = ('name', )
class OrderDetailSerializer(ModelSerializer):
product = ProductSerializer()
class Meta:
model = OrderDetail
fields = (
'id',
'product',
'amount',
'price'
)
class OrderSerializer(ModelSerializer):
details = OrderDetailSerializer(many=True)
status = serializers.CharField(source='get_status_display', read_only=True)
class Meta:
model = Order
fields = (
'id',
'status',
'created_at',
'external_id',
'details'
)
def create(self, validated_data):
details_data = validated_data.pop('details')
order = Order.objects.create(**validated_data)
for detail_data in details_data:
OrderDetail.objects.create(**detail_data, order=order)
return order