Django REST框架文件上传导致“不支持的媒体类型'multipart / form-data'”错误

9

我是Django和Django REST Framework的新手。我有以下序列化器类,我正在使用它来上传文件以及其他信息。但是,当我运行带有上传文件的API端点时,结果如下:

HTTP 415 Unsupported Media Type
Allow: POST, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "detail": "Unsupported media type \"multipart/form-data; boundary=----WebKitFormBoundaryybZ07gjZAqvcsZw3\" in request."
}

我很努力地在Google上解决这个问题,但是无法找到解决方案,所以这里是我的序列化器和API视图。

序列化器:

class ExampleSerializer(serializers.Serializer):

    example_id = serializers.IntegerField()
    description = serializers.CharField(allow_blank=True)
    example_file = serializers.FileField(allow_empty_file=True)

    def create_requirement_line(self):
        request = self.context['request']

        requirement_line = ExampleService().example_method(
            example_id=self.validated_data['example_id'],
            description=self.validated_data['description'],
            example_file=self.validated_data['example_file']
    )
    return requirement_line

视图:

 class RequirementLineAPIView(BaseCreateAPIView):

    serializer_class = ExampleSerializer
    parser_classes = (FormParser,)

    def post(self, request, format=None,*args, **kwargs):
        serializer = self.get_serializer(data=request.data)

        if serializer.is_valid():
            try:
                example_variable = serializer.example_method()
                return Response(example_variable, status=status.HTTP_200_OK)

            except ValidationError as e:
                return Response(e.message, status=status.HTTP_400_BAD_REQUEST)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)    

parser_classes = (FormParser,) 这行中,逗号的作用是什么? - kpie
我不确定,但如果我去掉逗号,那么就会出现“'type' object is not iterable”的错误。@kpie - Md. Tanvir Raihan
你能发更多的代码吗? - kpie
你能具体说明一下吗?因为这关乎到我的序列化类和API视图。@kpie - Md. Tanvir Raihan
parser_classes = (FormParser,)这一行中,逗号使其成为一个可迭代的变量,即一个Python元组。而DRF似乎需要它以这种方式存在。如果没有逗号,parser_classes变量将接收一个type值:即FormParser类。这将是一个等价的表达式:parser_classes = FormParser。为了更简单地理解,请在Python shell中尝试以下命令:x = 5 type(x) x = (5) type(x) x = (5,) type(x) x = 5, type(x)你得到了什么? - rodolfojcj
显示剩余2条评论
3个回答

10

如果您发送的是multipart/form-data,请使用MultiPartParser而不是FormParser。


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Md. Tanvir Raihan
好的,具体来说,我将发送一个整数(比如30)作为我的“example_id”,并将“This is a description”作为“description”,以及一个.pptx或.pdf文件作为“example_file”。@Ivan Genchev - Md. Tanvir Raihan
应该可以解决了:REST_FRAMEWORK = { ... 'UNICODE_JSON': False } - Ivan Genchev
但这与您最初的问题无关,而且该问题取决于您使用的设置、Python版本和DRF版本。 - Ivan Genchev
好的,在设置了 REST_FRAMEWORK = { ... 'UNICODE_JSON': False } 之后,现在我遇到了以下错误:'utf8' codec can't decode byte 0xff in position 14: invalid start byte。需要说明的是,我正在使用 Python2.7、DRF3.x 和 Django 1.9。 - Md. Tanvir Raihan
显示剩余2条评论

2
当访问request.DATA或request.FILES时,如果没有解析器能够处理请求数据的内容类型,则会引发此异常。
请参考Django REST Framework2文档中的UnsupportedMediaType
需要导入适合的解析器。
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser

class SampleView(APIView):
    parser_classes = (MultiPartParser,FormParser,JSONParser)

0

尝试使用FileField解析器{{link1:在Django Rest中使用解析器}}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接