The problem is that I have an array of objects [A1, A2, ..., An]. Right now when I need to post such an array I do it object by object. Is there any possibility to post the whole array at once, and recover an array of objects inside my Django View? If so, what is the pattern to follow here? I guess I could define a new model which is an array of my current model, create a serializer for it, etc., but this does not seem too elegant.
Below are my view and serializer:
model = SearchRequest
if request.method == 'POST':
#JSON to serializer object
serializer = SearchRequestSerializer(data=request.data, many=False)
if (serializer.is_valid() == False):
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#create the Python object
search_request = serializer.create()
#-- I do some processing stuff with the search_request object here ---
#object back to JSON
serializer3 = SearchRequestSerializer(search_request, many=False)
There are two solutions to your problem:
.create()method of your view
By default, django rest framework assumes you are passing it a single object. To account for the possibility to pass it a list of objects you might rewrite it as follows:
def create(self, request, pk=None, company_pk=None, project_pk=None): is_many = True if isinstance(request.data, list) else False serializer = self.get_serializer(data=request.data, many=is_many) 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)
Now your view will handle both single objects in
POST data as well as a list of objects.
django-rest-framework-bulk provides the above functionality plus additional features (e.g. bulk update). You can check it out and decide whether it fits your needs.
In order to get it to work with your function based view, the approach is similar:
@api_view(['POST']) def post_calculation(request): if request.method == 'POST': is_many = True if isinstance(request.data, list) else False # JSON to serializer object serializer = SearchRequestSerializer(data=request.data, many=is_many) if (serializer.is_valid() is False): # use `is False` syntax rather than `== False` in Python return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) serializer.save() #-- do some processing stuff here --- return Response(serializer.data)
Do not call
.create() method directly, use
.save() instead. Also, when using
many=False on serializer, the created instance is available under
serializer.instance. I am not sure how to obtain the list of created instances though. You can try the same
serializer.instance. If it doesn't work, try to find how to get it.