【问题标题】:django RequestFactory file uploaddjango RequestFactory 文件上传
【发布时间】:2023-03-24 18:30:01
【问题描述】:

我尝试使用 RequestFactory 创建请求并发布文件,但我没有得到 request.FILES。

    from django.test.client import RequestFactory
    from django.core.files import temp as tempfile

    tdir = tempfile.gettempdir()
    file = tempfile.NamedTemporaryFile(suffix=".file", dir=tdir)
    file.write(b'a' * (2 ** 24))
    file.seek(0)
    post_data = {'file': file}

    request = self.factory.post('/', post_data)
    print request.FILES  # get an empty request.FILES : <MultiValueDict: {}>

如何使用我的文件获取 request.FILES ?

【问题讨论】:

  • 你使用的是什么版本的 Django?使用 Django 1.4.5 这似乎可行,我得到&lt;MultiValueDict: {u'file': [&lt;TemporaryUploadedFile: tmpwXC4_p.file (application/octet-stream)&gt;]}&gt;

标签: django testing


【解决方案1】:

如果您先打开文件,然后将 request.FILES 分配给打开的文件对象,您就可以访问您的文件。

request = self.factory.post('/')
with open(file, 'r') as f:
    request.FILES['file'] = f
    request.FILES['file'].read()

现在您可以像往常一样访问 request.FILES 了。请记住,当您离开打开块时 request.FILES 将是一个关闭的文件对象。

【讨论】:

    【解决方案2】:

    我对@Einstein 的答案进行了一些调整,以使其适用于将上传文件保存在 S3 中的测试:

    request = request_factory.post('/')
    with open('my_absolute_file_path', 'rb') as f:
        request.FILES['my_file_upload_form_field'] = f
        request.FILES['my_file_upload_form_field'].read()
        f.seek(0)
        ...
    
    • 如果没有以 'rb' 身份打开文件,我的文件数据出现了一些不寻常的编码错误
    • 没有f.seek(0),我上传到 S3 的文件是零字节

    【讨论】:

      【解决方案3】:

      在更新您的FILES 之前,您需要提供正确的内容类型、正确的文件对象。

      from django.core.files.uploadedfile import File
      # Let django know we are uploading files by stating content type
      content_type = "multipart/form-data; boundary=------------------------1493314174182091246926147632"
      request = self.factory.post('/', content_type=content_type)
      # Create file object that contain both `size` and `name` attributes 
      my_file = File(open("/path/to/file", "rb"))
      # Update FILES dictionary to include our new file
      request.FILES.update({"field_name": my_file})
      

      boundary=------------------------1493314174182091246926147632 是多部分表单类型的一部分。我从我的网络浏览器完成的 POST 请求中复制了它。

      【讨论】:

        【解决方案4】:

        之前的所有答案都不适合我。这似乎是另一种解决方案:

        from django.core.files.uploadedfile import SimpleUploadedFile
        with open(file, "rb") as f:
            file_upload = SimpleUploadedFile("file", f.read(), content_type="text/html")
            data = {
                "file" : file_upload
            }
            request = request_factory.post("/api/whatever", data=data, format='multipart')
        

        【讨论】:

          【解决方案5】:

          确保“文件”确实是表单中文件输入字段的名称。 当它不是时我得到了那个错误(使用名称,而不是 id_name)

          【讨论】:

            猜你喜欢
            • 2013-03-27
            • 2011-09-21
            • 2011-07-31
            • 2011-03-18
            • 1970-01-01
            • 2013-05-08
            • 2011-06-27
            • 2016-03-11
            • 2017-01-18
            相关资源
            最近更新 更多