1

我有一个 django 文件模型,它有一个 models.FileField 字段和一个用于将文件上传到服务器的表单:

class UploadFile(model.Model):
    filename = models.FileField(upload_to='uploads')
    description = models.CharField(max_length=38, blank=True)

class UploadFileForm(ModelForm):
    class Meta:
        model = UploadFile
        fields = ('filename', 'description')

这是视图函数的样子:

def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            new_file = form.save()

现在我想要一个 python 脚本,它只使用标准库使用上面的视图函数将文件上传到 UploadFile 模型。但是,此代码不起作用,因为 POST 请求没有 FILES 方法。

import urllib, urllib2
data = urllib.urlencode({'filename': open(uploadfile, "rb"),
                        'description': 'upload test'})
post_req = urllib2.Request(upload_file_url, data)
result = urllib2.urlopen(post_req)

如何将 FILES 方法添加到 POST 请求以使用 python 脚本上传文件?我还尝试编写一个不使用表单但也不起作用的不同视图函数。

4

2 回答 2

6

要查看您的 django 视图是否有效,您可以使用浏览器对其进行测试:

<FORM action="{{ upload_file_url }}"
      enctype="multipart/form-data"
      method="POST">
  Description: <INPUT type="text" name="description" value="upload test"><BR>
  File to upload: <INPUT type="file" name="filename"><BR>
  <INPUT type="submit" value="Send">
</FORM>

仅使用 stdlib 以编程方式复制它很复杂。

multipart/form-data要像使用requests一样上传文件:

import requests

response = requests.post(upload_file_url,
                         files={'filename': open(uploadfile,'rb'),
                                'description': 'upload test'})
print response.content

或者urllib2poster库:

import urllib2

import poster.encode
import poster.streaminghttp

opener = poster.streaminghttp.register_openers()

params = {'filename': open(uploadfile,'rb'), 'description': 'upload test'}
datagen, headers = poster.encode.multipart_encode(params)
response = opener.open(urllib2.Request(upload_file_url, datagen, headers))
print response.read()
于 2013-06-06T18:12:06.230 回答
0

这不是那么容易,不是request没有FILES方法(这不是方法,是字典)。问题是如果请求没有Content-Type:multipart/form-data.

请注意,仅当请求方法为 POST 并且发布到请求的方法为 enctype="multipart/form-data" 时,FILES 才会包含数据。否则,FILES 将是一个空白的类字典对象。

在这里你可以看到这样的请求是什么样子的:一个包含多个文件的 Multipart HTTP 请求应该是什么样的?

https://docs.djangoproject.com/en/dev/ref/request-response/

所以基本上你要做的就是将该字段添加到你正在构建的请求中,然后将其发送到 django。

您可以查看 django 文档中的此页面以获取有关此内容的更多信息,如果您可以在将请求发送到 django 之前嗅探或查看请求的情况,那就太好了,这样您就可以知道缺少什么。

https://docs.djangoproject.com/en/dev/ref/forms/api/

由于对此没有简单/直接的答案,因此我希望这可以使您朝着正确的方向前进。

祝你好运!

于 2013-06-05T22:50:37.763 回答