In drf3 you can now implement a writable nested serializer by overriding the create() method and handling validated_data yourself. However, what if you've a multi-level nested relationship in the models like so:
class Order(models.Model):
"""
Order model to aggregate all the shipments created by a user at a particular time.
"""
created_at = models.DateTimeField(
verbose_name='created at',
auto_now_add=True
)
updated_at = models.DateTimeField(
verbose_name='updated at',
auto_now=True
)
class Shipment(models.Model):
"""
Many to One Relationship with the Orders Model. Aggregates all the details of a shipment being sent.
"""
created_at = models.DateTimeField(
verbose_name='created at',
auto_now_add=True
)
updated_at = models.DateTimeField(
verbose_name='updated at',
auto_now=True
)
order = models.ForeignKey(
to=Order
)
class ItemDetail(models.Model):
"""
Specifies details of the shipment contents. One to One relationship with the Shipment Model.
"""
shipment = models.OneToOneField(
to=Shipment,
primary_key=True
)
CONTENT_TYPES = (
('D', 'Documents'),
('P', 'Products')
)
content = models.CharField(
verbose_name='package contents',
max_length=1,
choices=CONTENT_TYPES,
default='P'
)
How would I write a serializer for order with custom create method to handle such a case? All the examples I've seen including the one on the official page has just one level of nested relationship.
Read is working fine with the depth argument. However, I'd really appreciate any help with writing the create/update method.
The writable nested serializer is explained in the documentation.
Please do not recreate a new serializer in the create/update. Once you hit the top most serializer create/update, all your data are validated, including the nested ones.
At this point, you'll have to write by yourself the mapping from the validated_data to your various objects.
I tried to make it automatic for DRF 2.x but it turns out that there was too many use case, some of which were exclusives. Therefore DRF leaves that work upon the developer - i.e. you.
One way is to have two serializers, firs
ItemDetailSerializer
which will callShipmentSirializer
to handleOrder
andShipment
creation and then createItemDetail
itself.Something like:
And for the
ShipmentSerializer
you can follow documentation about nested relations, that you've mentioned.