Issue
What is the difference between the above two methods?
I don't understand how they work, I did try googling, documentation, StackOverflow, medium articles but I don't understand the working.
Does ListCreateAPIView hit the create method as the length of the list? How to override that? ListSerializer, I don't get this at all. So I gotta have a parent list serializer and child model serializer.
Where do I add the validations in each of these methods? And what if I want to override the fields or save extra information.
Basically, I am trying to create an API endpoint for bulk-creating users. That means apart from just the validations, I need to set the password for each user being created in the backend. How do I save it that way?
When I tried using the ListCreateAPIView, it kept throwing me the error ListSerializer is not iterable even after I set many = True.
Does ListCreateAPI works with just the model serializer or do I need to set the class to a ListSerializer class?
And, when I followed this medium article on bulk creating using ListSerializer, it kept telling me something like "JSON parse error - Expecting ',' delimiter: line 4 column 20 (char 72)"
I seriously don't get the working of both ListSerializer and ListCreateAPIView.
Any help would be highly appreciated. I am a newbie to this rest API thingy. Thanks.
My code is just basic
serializers.py
class BulkCreateUsersListSerializer(serializers.ListSerializer):
def create(self, validated_data):
users = [UserModel(**item) for item in validated_data]
return UserModel.objects.bulk_create(users)
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = ...
fields = ...
list_serializer_class = BulkCreateUserListSerializers #commented when I tried using the ListCreateAPIView
views.py
class CreateBulkUsersAPIView(ListCreateAPIView):
serializer_class = UserSerializer
queryset = UserModel.objects.all()
def get_serializer(self, *args, **kwargs):
""" if an array is passed, set serializer to many """
if isinstance(kwargs.get('data', {}), list):
kwargs['many'] = True
return super(CreateBulkUsersAPIView, self).get_serializer(*args, **kwargs)
----Edit 1---- Traceback for "ListSerializer object is not iterable"
Template error:
In template C:\Users\Documents\Django Projects\startup\env\lib\site-packages\rest_framework\templates\rest_framework\horizontal\form.html, error at line 2
'ListSerializer' object is not iterable
1 : {% load rest_framework %}
2 : {% for field in form %}
3 : {% if not field.read_only %}
4 : {% render_field field style=style %}
5 : {% endif %}
6 : {% endfor %}
Solution
You had a lot of questions so I will choose one that will probably solve most of your problems:
ListCreateApiView
is for adding the functionality to list
objects via get
and create
objects via post
to your view.
The naming of ListCreateApiView
doesn't mean that you can create objects using a list (although the confusion is understandable). You can still support that though, but you need to write your own .create()
method in the view like so:
class CreateBulkUsersAPIView(ListCreateAPIView):
serializer_class = UserSerializer
queryset = UserModel.objects.all()
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data, many=True)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
The only difference with the default create
is get_serializer
needs to be called with many=True
to support creating a list of objects.
Answered By - Brian Destura
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.