【问题标题】:Django: Upload file via POST requestDjango:通过 POST 请求上传文件
【发布时间】:2018-12-13 21:19:23
【问题描述】:

我正在尝试通过 APIView 上传文件,但遇到了异常:{"exception": "ValidationException", "code": 401, "message": "You cannot access body after reading from request's data stream"} 这是我的代码:

API 视图:

class SetAvatarView(LoginRequiredAPIView):
    @csrf_exempt  # Does no affect to situation
    def post(self, request):
        try:
            request.account.update_avatar(request.FILES['file'])
        except ValidationException, e:
            return JsonResponse(e.to_dict(), status=400)
        return JsonResponse({}, 200)

Account模特:

class Account(models.Model):
    ...
    avatar = models.ImageField(upload_to=AVATARS_URL, default='default.jpg')
    ...
    def update_avatar(self, f):
        self.avatar = f

上传文件的测试代码:

def test_set_avatar(self):
    url = "/account/avatar/set/"
    with open("test.jpg", "r") as fp:
        response = self.client.post(url, {'file': fp}, #content_type='multipart/form-data', # Getting 400 Bad Request if uncomment
                                    **{'HTTP_AUTHORIZATION': 'Token 0ff0884090**********8ef5387423bc24cd15e1'})
    print response.content
    self.assertEqual(response.status_code, 200)

settings.py 中没有额外的中间件,我尝试禁用默认中间件,没有结果。

【问题讨论】:

  • 我觉得你需要fp.read()
  • 如果发送像{'file': fp.read()}这样的文件,我会收到{"error": "HTTP Status 415 - Unsupported Media Type"}
  • 如果这样发送并添加内容类型:image/jpeg,那么错误是Expecting property name: line 1 column 2 (char 1)
  • 尝试从这里添加format='multipart' stackoverflow.com/a/27576436/8060120
  • format='multipart with content-type 和 fp.read() 根本不影响

标签: python django file post uploading


【解决方案1】:

你必须在视图/account/avatar/set中对文件进行编码和解码

import base64 
def test_set_avatar(self):
    url = "/account/avatar/set/"
    with open("test.jpg", "r") as fp:
    response = self.client.post(url, {'file': base64.b64encode(fp.read())}, #content_type='multipart/form-data', # Getting 400 Bad Request if uncomment
                                **{'HTTP_AUTHORIZATION': 'Token 0ff0884090**********8ef5387423bc24cd15e1'})
    print response.content
    self.assertEqual(response.status_code, 200)

【讨论】:

  • 但实际上并没有解决原来的问题。是的,您可以将文件作为 base64 编码的字符串发送,但如果您打算以 HTML 形式或公共 API 使用此端点并且只想接收文件怎么办?
猜你喜欢
  • 1970-01-01
  • 2022-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-09
  • 2021-11-01
  • 1970-01-01
  • 2018-09-26
相关资源
最近更新 更多