Django FileField无法使用SimpleUploadedFile对象进行验证 [英] Django FileField not validating with a SimpleUploadedFile Object
问题描述
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屋!