BACKGROUND
I have two serializers: PostSerializer and PostImageSerializer which both inherit DRF ModelSerializer. The PostImage model is linked with Post by related_name='photos'.
Since I want the serializer to perform update, PostSerializer overrides update() method from ModelSerializer as stated in official DRF doc.
class PostSerializer(serializers.ModelSerializer):
photos = PostImageSerializer(many=True)
class Meta:
model = Post
fields = ('title', 'content')
def update(self, instance, validated_data):
photos_data = validated_data.pop('photos')
for photo in photos_data:
PostImage.objects.create(post=instance, image=photo)
return super(PostSerializer, self).update(instance, validated_data)
class PostImageSerializer(serializer.ModelSerializer):
class Meta:
model = PostImage
fields = ('image', 'post')
I have also defined a ViewSet which inherits ModelViewSet.
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
Finally the PostViewSet is registered to DefaultRouter. (Omitted code)
Goal
The goals are simple.
- Send PUT request via PostMan with url like 'PUT http://localhost:8000/api/posts/1/'
- Since Image files should be included, request would be done by form-data like below.
Problem
I'm getting 400 Response with error message as following.
{
"photos": [ "This field is required." ],
"title": [ "This field is required." ],
"content": [ "This field is required." ]
}
(Should you plz note that the error messages might not exactly fit with DRF error messages since they are translated.)
It is obvious that none of my PUT fields are applied. So I have been digging around Django rest framework source code itself and found out serializer validation in ViewSet update() method continues to fail.
I doubt that because I PUT request not by JSON but by form-data using key-value pair so request.data is not properly validated.
However, I should contain multiple images in the request which means plain JSON would not work.
What would be the most clear solutions for this case?
Thank you.
Update
As Neil pointed out, I added print(self) at the first line of update() method of PostSerializer. However nothing printed out on my console.
I think this is due to my doupt above because perform_update() method which calls serializer update() method is called AFTER serializer is validated.
Therefore the main concept of my question could be narrowed to the followings.
- How should I fix requested data fields so that validation inside update() method of ModelViewSet could pass?
- Do I have to override update() method of ModelViewSet(not the one from ModelSerializer)?
Thanks again.