Django FileField不用SimpleUploadedFile对象进行验证

我通过ajax上传文件,然后创建一个SimpleUploadFile对象并传递它来替换request.FILES - 这不会传递form.is_valid()。 我已经记录下SimpleUploadedFile字典和request.FILES替换; 正如你所看到的,SimpleUploadedFile对象能够被创建:

SimpleUploadedFile [This does not work.]:
{'book_pics': <SimpleUploadedFile: movies.jpg (text/plain)>} # Yielded by printing uploaded_file

当我不使用ajax并简单地使用表单提交文件时[我是出于好奇],这里是uploaded_file的样子:

request.FILE generated InMemoryUploadedFile [This works.]:
<MultiValueDict: {u'book_pics': [<InMemoryUploadedFile: movies.jpg (image/jpeg)>]}>

任何想法如何我可以让SimpleUploadedFile验证?

def add_book(request):
    if request.method == 'POST':
        # Grabbing the file uploaded via ajax earlier.
        fh = File(file(settings.MEDIA_ROOT + request.POST['book_pics']))
        uploaded_file = {'book_pics':SimpleUploadedFile(fh.name, fh.read())}
        form = BookForm(data=request.POST, files=uploaded_file)
        if form.is_valid():
            print >> sys.stderr, "Form is valid."
            form.save()
            return render(request, 'generic_message.html', {'message': 'Succesfully added book.'})
        else:
           ...
    else:
        ...

根据这些文档,SimpleUploadedFile应该可以工作:https://docs.djangoproject.com/en/dev/ref/forms/api/

编辑:

当我打印f.clean(my_file)时,出现以下错误,下面的内容。 在my_file中设置filetype时会发生这种情况:

fh = File(file(settings.MEDIA_ROOT + request.POST['book_pics']))
my_file = UploadedFile(fh.name, fh.read(), 'image/jpeg')
f = forms.FileField()
print >> sys.stderr, f.clean(my_file)
# f.clean(my_file) Returns an error: 

DjangoUnicodeDecodeError: 'utf8' codec can't decode byte 0x92 in position 18: invalid 
start byte. You passed in '<UploadedFile: 
Xx06x18x92HIxdexf0x00xddx7fnx8exf9x8fxe5x00x92IGaxaaxcexfe_xa4x04xe
3xcax1a,x97x99xd0xdax02xe3exa8xbb=x99xe0x00x0bxfd?
Qx00x02x80x00*xe6xf7xb0xd6xfb@x06xd2x1f7xfdxafx00x04Iw}x8bx08xbcxBxc
bjx1exa3x7f1xf9xc3xc3xef"rxfbxcc"Txa2x01rxe7Xxb0xa3xc4rxeaxdfx9cx00>
x96Kx0bxeex07xd26<xa0rxb8xf2?xa4x94xf96xe43x1fxc5xfax1fxd8@ 
txe9xeax7f8x00p?Sxf9xc0x01xc6xaax1bx06axca-
x1fxbax88xa6xedn,|'xa2xd8txb0x862xb0xfax17x16<xf7x80xc1xcexc3xccx
fex91Xpx02xc5x92x96xb3xa9x8boxac8x0eQxa1xf3x80x07(xf8GRxf1xxf0x80($xa
8x02K76xda4x03hx07x9fxedx00x07x1fx12Fxc7xfbCxc3x90x16txcaxeeu;xf4x8a
x92x9f#xa4x12Arxf7x80AxcaIdxdfRxc7xaexb0xf0x01i%xc5xf7x8ax80PItxb9xb
9 xfd`x01xc2Ixe6}x81x1bx7f*7x8ax1c'O|x84xc1xc...

从我的一个测试中:

name = 'filename'
f = file(self.TEST_ROOT + name)
file_data = {'file':SimpleUploadedFile(f.name,f.read())}
data = {}
form = self.TestForm(data,file_data)
self.assertTrue(form.is_valid())

这个测试正在通过。 我的代码几乎和你的一样,除了我没有传递一个文件,而是一个文件到表单。 而且我没有说出通过的论点。 两种差异都没有什么不同,我试过了。 你的问题在于

file(settings.MEDIA_ROOT + request.POST['book_pics'])

request.POST ['book_pics']包含文件名,但您的文件不在MEDIA_ROOT中。 它位于django放置临时上传文件的位置,或者如果它是一个小文件,它位于内存中。 无论哪种方式,您用代码创建的路径都不指向该文件。

如果您尝试通过ajax发送文件,而不是使用表单,则可以使用类似下面的解决方案来实现:http://kuhlit.blogspot.de/2011/04/ajax-file-uploads-and-csrf -in-django-13.html查看该页面中间某处的django代码。

相当复杂,但它的工作原理。

链接地址: http://www.djcxy.com/p/56553.html

上一篇: Django FileField not validating with a SimpleUploadedFile Object

下一篇: Django, validating Form