Django FileField无法使用SimpleUploadedFile对象进行验证 [英] Django FileField not validating with a SimpleUploadedFile Object

查看:624
本文介绍了Django FileField无法使用SimpleUploadedFile对象进行验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过ajax上传文件,然后创建一个SimpleUploadFile对象并将其传递给replace.FILES - 这不会通过form.is_valid()。我已经登录了SimpleUploadedFile字典并请求.FILES替换下面;您可以看到,可以创建SimpleUploadedFile对象:

  SimpleUploadedFile [这不起作用]:
{'book_pics':< SimpleUploadedFile:movies.jpg(text / plain)>}#通过打印uploaded_file

当我不使用ajax,只需使用表单提交文件[我做出了好奇],这里是upload_file的样子:

  request.FILE生成InMemoryUploadedFile [这个工作。]:
< MultiValueDict:{u'book_pics':[< InMemoryUploadedFile:movies.jpg(image / jpeg)> ;]}>

有什么想法可以让SimpleUploadedFile验证吗?

  def add_book(request):
如果request.method =='POST':
#提前通过ajax上传的文件。
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)
如果form.is_valid():
print>> sys.stderr,表单有效。
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 =文件(文件(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)返回错误:

DjangoUnicodeDecodeError:'utf8'编解码器无法解码位置18的字节0x92:无效
开始字节。您在<已上传文件:
X\x06\x18\x92HI\xde\xf0\x00\xdd\x7f\\\
\x8e\xf9\x8f\\ \\xe5\x00\x92IGa\xaa\xce\xfe_\xa4\x04\xe
3\xca\x1a,\x97\x99\xd0\xda \x02\xe3e\xa8\xbb = \x99\xe0\x00\x0b\xfd?
Q\x00\x02\x80\x00 * \xe6\xf7\xb0\xd6\xfb @ \x06\xd2\x1f7\xfd\xaf\\ \\ x00\x04Iw} \x8b\x08\xbcxB\xc
bj\x1e\xa3\x7f1\xf9\xc3\xc3\xefr\xfb\\ \\ xccT\xa2\x01r\xe7X\xb0\xa3\xc4r\xea\xdf\x9c\x00> \
x96K\x0b\xee\ x07\xd26< \xa0\r\xb8\xf2 \xa4\\\x94\xf96\xe43\x1f\xc5\xfa\x1f\xd8 @
t\xe9\xea\x7f8\x00p?S\xf9\xc0\x01\xc6\xaa\x1b\x06a\xc-
\x1f \xba\x88\xa6\xedn,| \'\xa2\xd8t\xb0\x862\\\xb0\xfa\x17\x16< \xf7\\ \\ x80\xc1\xce\xc3\xcc\x
fe \x91Xp\x02\xc5\x92\x96\xb3\xa9\x8bo\xac 8\x0eQ\xa1\xf3\x80\x07(\xf8GR\xf1x\xf0\x80($ \xa
8\x02K76\xda4\x03h\ x07\x9f\xed\x00\x07\x1f\x12F\xc7\xfbC\xc3\x90\x16\t\xca\xeeu; \xf4\x8a
\x92\x9f#\xa4\x12Ar\xf7\x80A\xcaId\xdfR\xc7\xae\xb0\xf0\x01i%\xc5\ xf7\x8a\x80PI\t\xb9\xb
9 \xfd`\x01\xc2I\xe6} \x81\x1b\x7f * 7\x8a\\ \\ x1c\'O | \x84\\\xc1\xc ...


解决方案

从我的一个测试中:

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

这个测试是通过的。我的代码与你的代码几乎相同,除非我没有传递一个文件,而是将一个文件传递给表单。而且我没有把传递的参数命名。这两个差异没有什么不同,我已经尝试过了。你的问题是在

 文件(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代码



相当复杂,但它有效。


I am uploading a file via ajax, and then creating a SimpleUploadFile object and passing it to replace request.FILES -- this does not pass form.is_valid(). I've logged the SimpleUploadedFile dictionary and request.FILES replacement below; as you can see, the SimpleUploadedFile object is able to be created:

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

When I don't use ajax and simply use the form to submit the file [I did this out of curiousity], here is what uploaded_file looks like:

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

Any idea of how I could get the SimpleUploadedFile to validate?

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:
        ...

According to these docs, SimpleUploadedFile should work: https://docs.djangoproject.com/en/dev/ref/forms/api/

EDIT:

When I print f.clean(my_file) I get the following error, context below. This happens with and without setting filetype in my_file:

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: 
X\x06\x18\x92HI\xde\xf0\x00\xdd\x7f\n\x8e\xf9\x8f\xe5\x00\x92IGa\xaa\xce\xfe_\xa4\x04\xe
3\xca\x1a,\x97\x99\xd0\xda\x02\xe3e\xa8\xbb=\x99\xe0\x00\x0b\xfd?
Q\x00\x02\x80\x00*\xe6\xf7\xb0\xd6\xfb@\x06\xd2\x1f7\xfd\xaf\x00\x04Iw}\x8b\x08\xbcxB\xc
bj\x1e\xa3\x7f1\xf9\xc3\xc3\xef"r\xfb\xcc"T\xa2\x01r\xe7X\xb0\xa3\xc4r\xea\xdf\x9c\x00>\
x96K\x0b\xee\x07\xd26<\xa0\r\xb8\xf2?\xa4\\\x94\xf96\xe43\x1f\xc5\xfa\x1f\xd8@ 
t\xe9\xea\x7f8\x00p?S\xf9\xc0\x01\xc6\xaa\x1b\x06a\xca-
\x1f\xba\x88\xa6\xedn,|\'\xa2\xd8t\xb0\x862\\\xb0\xfa\x17\x16<\xf7\x80\xc1\xce\xc3\xcc\x
fe\x91Xp\x02\xc5\x92\x96\xb3\xa9\x8bo\xac8\x0eQ\xa1\xf3\x80\x07(\xf8GR\xf1x\xf0\x80($\xa
8\x02K76\xda4\x03h\x07\x9f\xed\x00\x07\x1f\x12F\xc7\xfbC\xc3\x90\x16\t\xca\xeeu;\xf4\x8a
\x92\x9f#\xa4\x12Ar\xf7\x80A\xcaId\xdfR\xc7\xae\xb0\xf0\x01i%\xc5\xf7\x8a\x80PI\t\xb9\xb
9 \xfd`\x01\xc2I\xe6}\x81\x1b\x7f*7\x8a\x1c\'O|\x84\\\xc1\xc...

解决方案

From one of my tests:

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

This test is passing. My code is almost identical to yours, except i'm not passing a File but a file to the form. And i do not name the arguments passed. Both differences don't make a difference, i have tried that. Your problem is that in

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

request.POST['book_pics'] does contain the filename, but your file is not in MEDIA_ROOT. It is in the location where django puts temporary uploaded files, or, if it is a small file, it is in memory. Either way the path you create with your code does not point to the file.

If you try to send the file via ajax, and not with a form, you can do that with a solution like this one: http://kuhlit.blogspot.de/2011/04/ajax-file-uploads-and-csrf-in-django-13.html Have a look at the django code somewhere in the middle of that page.

Quite complex, but it works.

这篇关于Django FileField无法使用SimpleUploadedFile对象进行验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆