Reputation: 773
What is the difference between customizing the "create" method in DRF viewset or customizing it in the serializer? I understand the serializer is responsible to deserialize the data, i.e. the way the data is presented in the POST query; however, I can also create objects in related fields in the serializer.
#views.py
def create(self, request):
pass
#serializer.py
def create(self, validated_data):
return Model.objects.create(**validated_data)
When should I customize views/create vs. serializer/create?
Upvotes: 15
Views: 17943
Reputation: 3805
create
method from viewsetThis method handles the POST
request logic in the view, which by default does:
is_valid
method on the serializer.save()
method on serializerResponse
with serialized data and 201 statusYou don't really need to override the create
method on viewset, if is something that you need to send to the serializer from the view itself you can override perform_create
which by default does serializer.save()
. Eg. if you want to send the user from the request you can do:
def perform_create(self, serializer):
# here you will send `created_by` in the `validated_data`
serializer.save(created_by=self.request.user)
Note: Behind the scene save
method will execute the create
method on serializer with the validated_data
create
method from serializerThis method just creates the actual model instance using the validated_data
. You may override this method in case you need to create related objects, like the following:
def create(self, validated_data):
items_data = validated_data.pop('items')
# similar to Parent.objects.create(**validated_data)
parent = super().create(**validated_data)
for item_data in items_data:
Item.objects.create(parent=parent, **item_data)
return parent
So here you are sending a payload with data regarding the Parent
object but also a list of items
with their representation, so now the create
method will create also the Items and link them with the Parent instance.
To summarize this:
Upvotes: 33