django RequestFactory文件上传

时间:2013-01-26 19:01:59

标签: django testing

我尝试使用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?

5 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:2)

在更新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是多部分表单类型的一部分。我从我的webbrowser发出的POST请求中复制了它。

答案 2 :(得分: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 :(得分:0)

确保'file'确实是表单中文件输入字段的名称。 当它不是(使用名称,而不是id_name)

时,我得到了该错误

答案 4 :(得分:0)

以前的所有答案都不适用于我。这似乎是一种替代解决方案:

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')