4

I am trying to upload file with some form data. For testing my api I am using Postman.When I try to POST with file and other fields, I got this error

{
  "detail": "JSON parse error - 'utf-8' codec can't decode byte 0xbf in position 10: invalid start byte"
}

Here is my model:

class Music(models.Model):
    album = models.ForeignKey(Album, related_name='tracks')
    playlist = models.ForeignKey(Playlist, null=True, related_name='tracks')
    name = models.CharField(max_length=200, unique=True)
    dropbox_id = models.CharField(max_length=500, null=True)
    favorite = models.BooleanField(default=False)
    created_at = models.DateField(auto_now_add=True)
    counter = models.IntegerField(default=0)

serializer:

class MusicSerializer(serializers.ModelSerializer):
    file = serializers.FileField(required=True)

    class Meta:
        model = Music
        fields = ('id', 'favorite', 'created_at', 'counter', 'file', 'name', 'album', 'playlist')

and view :

class MusicViewSet(viewsets.ModelViewSet):
    queryset = Music.objects.all()
    serializer_class = MusicSerializer

    def perform_create(self, serializer):
        file_obj = self.request.FILES['file']
        dbx = dropbox.Dropbox(JSON_DATA['dropbox_access_token'])
        res = dbx.files_upload(file_obj, '/', autorename=True, mute=True)
        print(res)
        serializer.save(dropbox_id='x')
5
  • Have you set "content-type: application/json" in HEADER? Commented Jun 23, 2016 at 9:17
  • Yes of course. There are three headers : Authorization, Accept and Content-Type Commented Jun 23, 2016 at 9:23
  • Content-type is not needed. Remove it and then check. Commented Jun 23, 2016 at 9:28
  • Can you show the request? I suspect that you can not upload the file the way you are trying to... Also as a starting point look at this: gist.github.com/yprez/7704036 Commented Jun 23, 2016 at 9:53
  • 2
    Json cannot be used to send direct files, you should send data with multipart/form-data content type instead. Also, you would need to specify a MultiPartParser in parser_classes in your ViewSet then if its not specified in the settings. Commented Jun 23, 2016 at 16:32

1 Answer 1

10

You cannot upload files with JSON request content.

You should instead send data with multipart/form-data content. DRF's MultiPartParser handles multipart HTML form content which supports file uploads.

MultiPartParser
Parses multipart HTML form content, which supports file uploads. Both request.data will be populated with a QueryDict.

You will typically want to use both FormParser and MultiPartParser together in order to fully support HTML form data.

In your MusicViewSet, you can define FormParser and MultiPartParser, if they are not defined in your settings so that DRF can parse the multipart HTML form content. You can access the file using serializer.validated_data in perform_create() method.

class MusicViewSet(viewsets.ModelViewSet):
    queryset = Music.objects.all()
    serializer_class = MusicSerializer
    parser_classes = (FormParser, MultiPartParser) # set parsers if not set in settings. Edited

    def perform_create(self, serializer):
        file_obj = serializer.validated_data['file'] # access file
        dbx = dropbox.Dropbox(JSON_DATA['dropbox_access_token'])
        res = dbx.files_upload(file_obj, '/', autorename=True, mute=True)
        serializer.save(dropbox_id='x')
Sign up to request clarification or add additional context in comments.

6 Comments

Now I got this error { "detail": "Multipart form parse error - Invalid boundary in multipart: None" }
@pyprism What is the content-type header you are sending?
multipart/form-data
Using postman, you just need to select 'form data' option without adding content-type header. There you should add the file along with other keys.
Also check this link for file upload using Postman. stackoverflow.com/questions/16015548/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.