Issue
I have a very simple model and its related serializer and views:
class Page(models.Model):
user = models.ForeignKey(User)
title = models.CharField(max_length=255)
pub_date = models.DateTimeField(default=timezone.now)
class PageSerializer(serializers.ModelSerializer):
class Meta:
model = Page
fields = ('user', 'title', 'pub_date')
class PageViewSet(viewsets.ModelViewSet):
queryset = Page.objects.all()
serializer_class = PageSerializer
Now I can post like this:
{
"user": 1,
"title": "Lorem ipsum"
}
This works fine. But I would like to post multiple objects like this:
[
{
"user": 1,
"title": "Lorem ipsum one"
},
{
"user": 1,
"title": "Lorem ipsum two"
}
]
But this gives me an error:
"non_field_errors": [
"Invalid data. Expected a dictionary, but got list."
]
So to accept multiple objects I modified the view as per the doc:
class PageViewSet(viewsets.ModelViewSet):
queryset = Page.objects.all()
serializer_class = PageSerializer(queryset, many=True)
But I am getting an error:
TypeError at /api/blog/pages/
'ListSerializer' object is not callable
What am I missing here?
Solution
You had it set up correctly before, the serializer_class should point to the class like this:
serializer_class = PageSerializer
You were right on the error, it doesn't like receiving multiple objects in the POST. One way to fix it would be to override the get_serializer method n the view, adding in many=True there.
Something like:
def get_serializer(self, *args, **kwargs):
if "data" in kwargs:
data = kwargs["data"]
# check if many is required
if isinstance(data, list):
kwargs["many"] = True
return super(PageViewSet, self).get_serializer(*args, **kwargs)
To answer your question in the comments: isinstance()
is a Python method to check the type of an object. In this case, it's a list
when passing in multiple objects, so we just check what type data
is and set many=true
if it's a list
.
DRF docs regarding get_serializer (under methods)
Python docs regarding isinstance
Answered By - Cody Parker
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.