尝试使用Requests和Django将文件发送到服务器的多个错误消息

时间:2016-08-02 16:50:16

标签: python django django-views python-requests

我目前正在使用Requests库从表单(InMemoryUploadedFile)向远程服务器发送文件。我最初发送了'文件'(file = self.request.FILES.get('file'))作为我的有效负载的一部分,当我运行代码时,我收到了来自服务器的JSON错误响应:

  

{"结果":"错误","消息":"字符串包含空字节"}

进一步阅读(https://docs.djangoproject.com/en/1.9/ref/files/uploads/)后,似乎读取文件是有意义的。所以我决定使用.chunks()方法读取文件(如果文件大于2.5MB),但现在我得到了:

  

{"结果":"错误","消息":" UTF-8中无效的字节序列"}

如果我使用.multiple_chunks(),我会收到服务器500错误。

有没有人有任何想法可以采取哪些措施来解决这个问题?

class AddDocumentView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
    login_url = reverse_lazy('users:login')
    form_class = FileUploadForm
    template_name = 'docman/forms/add-document.html'
    success_message = 'Document was successfully added'

    def form_valid(self, form):
        pk = self.kwargs['pk']
        user = get_object_or_404(User, pk=pk)
        file = self.request.FILES.get('file')
        if not self.post_to_server(file, user.id):
            messages.error(self.request,  "Upload failed", extra_tags='alert alert-danger')
        return render(self.request, self.template_name, {'form': form})

    def post_to_server(self, file, cid):
        url = 'https://exampleapi.herokuapp.com/api/files/'
        headers = {'token': 'secret-token93409023'}
        payload = {'file': file.chunks(), 'client_id': cid}
        r = requests.post(url, data=payload, headers=headers)
        print(r.text)
        if r.status_code == requests.codes.ok:
            return True
        else:
            return False

1 个答案:

答案 0 :(得分:0)

我想通了,它与我发送文件作为有效载荷的一部分有关,这不会对上传进行多部分编码。所以我要做的就是将文件作为正确的“文件”参数发送,该参数可以正确地对上传进行多部分编码。

class AddDocumentView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
    login_url = reverse_lazy('users:login')
    form_class = FileUploadForm
    template_name = 'docman/forms/add-document.html'
    success_message = 'Document was successfully added'

    def form_valid(self, form):
        pk = self.kwargs['pk']
        user = get_object_or_404(User, pk=pk)
        file = self.request.FILES.get('file')
        if not self.post_to_server(file, user.id):
            messages.error(self.request,  "Upload failed", extra_tags='alert alert-danger')
        return render(self.request, self.template_name, {'form': form})

    def post_to_server(self, file, cid):
        url = 'https://exampleapi.herokuapp.com/api/files/'
        headers = {'token': 'secret-token93409023'}
        # Remove files as part of payload
        payload = {'client_id': cid}
        files = {'file': file}
        # Place 'files' as file paramter to be properly multipart encoded
        r = requests.post(url, files=files, data=payload, headers=headers)
        print(r.text)
        if r.status_code == requests.codes.ok:
            return True
        else:
            return False