Writable nested serializer in django-rest-framework?
Nested Serializer
You can do something like this, define a serializer for Dataitem
that can reuse a serializer of the AssetModel
model
class AssetModelSerializer(serializers.ModelSerializer):
class Meta:
model = AssetModel
# Fields org and name of AssetModel will be inlcuded by default
class DataitemSerializer(serializers.ModelSerializer):
class Meta:
model = Dataitem
mod = AssetModelSerializer()
# This is the Dataitem.mod field
# which is a FK to AssetModel,
# Now it'll be serilized using the AssetModelSerializer
# and include the org and name fields of AssetModelSerializer
I prefer this approach because of the control I get. If you serialize using the above you get a structure like this:
data_item = {'name': ..., 'mod': {'org': ..., 'name': ...}}
^
|___ AssetModel fields
Alternatively you can also use depth = n
You can also use depth = 1
in Dataitem
class DataitemSerializer(serializers.ModelSerializer):
class Meta:
model = Dataitem
depth = 1 # Will include fields from related models
# e.g. the mod FK to AssetModel
Writable Nested Serializer
Because the behavior of nested creates and updates can be ambiguous, and may require complex dependencies between related models, REST framework 3 requires you to always write these methods explicitly.
We have to implement create/update
to make this writable as per DRF's documentation
class DataitemSerializer(serializers.ModelSerializer):
class Meta:
model = Dataitem
# Nested serializer
mod = AssetModelSerializer()
# Custom create()
def create(self, validated_data):
# First we create 'mod' data for the AssetModel
mod_data = validated_data.pop('mod')
asset_model = AssetModel.objects.create(**mod_data)
# Now we create the Dataitem and set the Dataitem.mod FK
dataitem = Dataitem.objects.create(mod=asset_model, **validated_data)
# Return a Dataitem instance
return dataitem
There seems to be a library that does this drf-writable-nested
it handles the creation and serialisation of these types
- OneToOne (direct/reverse)
- ForeignKey (direct/reverse)
- ManyToMany (direct/reverse excluding m2m relations with through model)
- GenericRelation (this is always only reverse)