How to use MultiPartParser in Django Rest Framework

Jenia Ivanov picture Jenia Ivanov · Oct 27, 2017 · Viewed 11.9k times · Source

I need to upload a file and some JSON associated with it. But I don't understand how to save the different parts, specifically the JSON part i.e. I'm able to save the image but not the JSON.

I read that I need to use a MultiPartParser but I can't figure out how to integrate it correctly into my serializer class.

Here is the multi-part request that my Server is receiving:

<QueryDict: {'geo': ['{"point" : { "type:" : "Point", "coordinates" : [11.51350462236356, -22.70903491973877]}}'], 'picture': [<TemporaryUploadedFile: photo3.jpg (image/*)>]}>

Here is the view:

class UserUploadedPicture(APIView):

    def post(self, request, format=None):
        print(request.data)
        print("\n\n\n")
        serializer = PictureSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data)
        return JsonResponse(serializer.errors, status=400)

Here is the serializer:

class PictureSerializer(GeoFeatureModelSerializer):
    class Meta:
        model = Pictures
        geo_field = "point"
        fields = ('picture', 'processed', 'flagged', 'point')

Here is the model:

class Pictures(models.Model):
    objects = models.GeoManager()
    picture = models.ImageField(null=True, default=None, blank=True)
    processed = models.BooleanField(default=False)
    flagged = models.BooleanField(default=False)
    point = models.PointField(null=True, default=None, blank=True)

Can anyone please tell me how to serialize the point field correctly? Maybe I need to change the JSON format? Maybe I need to change the serializer?

Answer

Anas Tiour picture Anas Tiour · Oct 27, 2017

As to integrating the MultiPartParser, it is done with the View, since it is responsible of receiving the request and handling it, not the Serializer. You are using a class-based view and defining the parser is done using the parser_classes attribute as explained in the same link to the official documentation you provided.

So your View becomes:

class UserUploadedPicture(APIView):
    parser_classes = (MultiPartParser, )

    def post(self, request, format=None):
        print(request.data)
        print("\n\n\n")
        serializer = PictureSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data)
        return JsonResponse(serializer.errors, status=400)

And concerning your Serializer for the PointField, check this SO answer