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')
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
Parsesmultipart
HTML form content, which supports file uploads. Bothrequest.data
will be populated with aQueryDict
.You will typically want to use both
FormParser
andMultiPartParser
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')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With