如何从React将文件发送到Django REST Framework?

时间:2019-07-19 21:56:14

标签: reactjs django-rest-framework

我需要从基于React的前端向Django REST Framework后端发送任意文件(例如xls)。

谷歌搜索并尝试了许多代码变体几个小时,但没有一个能完全起作用。

这是代码的重要组成部分:

  1. 反应

1.1表单输入字段

<input
    type="file"
    multiple={true}
    accept=".xls,.xlsx,.csv,.txt"
    onChange={this.handleFilesChosen}
/>

1.2 handleFilesChosen

    handleFilesChosen = event => {
        this.setState({
            files: event.target.files
        });
    }

1.3上传点击处理程序(authHeader是替换授权承载令牌的函数)

    handleUploadClick = event => {
        let formData = new FormData();
        for (let file of this.state.files) {
            formData.append('files', file);
        }
        const csrf = this.getCookie('csrftoken');
        fetch(`${API_BASE_PATH}/load-input-data/`, {
            method: 'POST',
            headers: authHeader({contentType: 'multipart/form-data', csrf: csrf}),
            body: formData,
        })
        .then(result => result.json())
        .catch(error => error);
    }
  1. DRF视图
class LoadInputDataView(APIView):
    parser_class = (MultiPartParser,)

    @method_decorator(login_required)
    def post(self, request, format=None):
        print(request.data)
        return Response(status=status.HTTP_201_CREATED)

我选择了带有hello world内容的简单txt文件(为了使调试容易,二进制文件将在以后发布),将其上传并在Django <QueryDict: {}>控制台中获取runserver

如果我查看Chrome的“网络”标签,则会看到以下空的请求有效负载,而不是实际的文件内容:

------WebKitFormBoundaryYw6ABRFkvxatzHqi
Content-Disposition: form-data; name="files"; filename="foo.txt"
Content-Type: text/plain


------WebKitFormBoundaryYw6ABRFkvxatzHqi--

试图删除contentType标头-消息JSON parse error出现400错误(浏览器自动替换JSON contentType标头)。

我被困住了。有人可以引导我吗?

1 个答案:

答案 0 :(得分:0)

找到解决方案。我不应该手动设置Content-Type标头,而是使用boundary选项自动设置。现在Django的request.FILES也可以使用,我可以使用以下代码处理来自后端的上传文件:

class ParseInputDataView(APIView):
    parser_class = (MultiPartParser,)
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request, controller_id, format=None):
        for file_entry in request.FILES.getlist('files'):
            uploaded_file_name = file_entry.name
            uploaded_file_content = file_entry.read()
            ...