【问题标题】:Django REST Framework file uploadDjango REST 框架文件上传
【发布时间】:2016-10-25 12:37:47
【问题描述】:

我正在尝试上传带有一些表单数据的文件。为了测试我的 api,我正在使用 Postman。当我尝试使用文件和其他字段进行 POST 时,我收到了这个错误

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

这是我的模型:

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)

序列化器:

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

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

并查看:

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')

【问题讨论】:

  • 你是否在 HEADER 中设置了“content-type: application/json”?
  • 当然可以。共有三个标头:Authorization、Accept 和 Content-Type
  • 不需要内容类型。删除它然后检查。
  • 你能显示请求吗?我怀疑您无法按照您尝试的方式上传文件...也可以作为起点查看:gist.github.com/yprez/7704036
  • Json 不能用于发送直接文件,您应该发送 multipart/form-data 内容类型的数据。此外,如果未在设置中指定,则需要在 parser_classes 中指定 MultiPartParser ViewSet

标签: django django-rest-framework


【解决方案1】:

您不能上传带有JSON 请求内容的文件

您应该发送带有multipart/form-data 内容的数据。 DRF 的MultiPartParser 处理支持文件上传的多部分 HTML 表单内容。

MultiPartParser
解析multipart HTML 表单内容,支持 文件上传。两个request.data 都将填充QueryDict

您通常希望同时使用 FormParserMultiPartParser 为了完全支持 HTML 表单数据。

在您的MusicViewSet 中,您可以定义FormParserMultiPartParser,如果它们未在您的设置中定义,以便 DRF 可以解析多部分 HTML 表单内容。您可以在perform_create() 方法中使用serializer.validated_data 访问file

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')

【讨论】:

  • 现在我收到了这个错误{ "detail": "Multipart form parse error - Invalid boundary in multipart: None" }
  • @pyprism 您发送的content-type 标头是什么?
  • 多部分/表单数据
  • 使用邮递员,您只需要选择“表单数据”选项而不添加内容类型标题。您应该在此处添加文件以及其他键。
  • 还可以检查此链接以使用 Postman 上传文件。 stackoverflow.com/questions/16015548/…
猜你喜欢
  • 2015-10-04
  • 2013-12-26
  • 2016-02-16
  • 2021-09-27
  • 2013-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多