gui*_*nny 8 python django file
我想知道是否有办法将zip文件上传到django web服务器并将zip文件放入django数据库而不访问过程中的实际文件系统(例如将zip文件解压缩到tmp目录然后加载它们)
Django提供了一个将python文件转换为Django文件的函数,所以如果有一种方法将ZipExtFile转换为python文件,它应该没问题.
感谢帮助!
Django模型:
from django.db import models
class Foo:
file = models.FileField(upload_to='somewhere')
Run Code Online (Sandbox Code Playgroud)
用法:
from zipfile import ZipFile
from django.core.exceptions import ValidationError
from django.core.files import File
from io import BytesIO
z = ZipFile('zipFile')
istream = z.open('subfile')
ostream = BytesIO(istream.read())
tmp = Foo(file=File(ostream))
try:
tmp.full_clean()
except Validation, e:
print e
Run Code Online (Sandbox Code Playgroud)
输出:
{'file': [u'This field cannot be blank.']}
Run Code Online (Sandbox Code Playgroud)
[解决方案]解决方案使用丑陋的黑客:
正如Don Quest正确指出的那样,类似文件的类(如StringIO或BytesIO)应将数据表示为虚拟文件.但是,Django File的构造函数只接受内置文件类型而不接受任何其他内容,尽管类文件类也可以完成这项工作.黑客是手动设置Django :: File中的变量:
buf = bytesarray(OPENED_ZIP_OBJECT.read(FILE_NAME))
tmp_file = BytesIO(buf)
dummy_file = File(tmp_file) # this line actually fails
dummy_file.name = SOME_RANDOM_NAME
dummy_file.size = len(buf)
dummy_file.file = tmp_file
# dummy file is now valid
Run Code Online (Sandbox Code Playgroud)
如果您有更好的解决方案,请继续评论(自定义存储除外)
在不知道Django的情况下,我可以告诉你看一下"io"包.你可以这样做:
from zipfile import ZipFile
from io import StringIO
zname,zipextfile = 'zipcontainer.zip', 'file_in_archive'
istream = ZipFile(zname).open(zipextfile)
ostream = StringIO(istream.read())
Run Code Online (Sandbox Code Playgroud)
然后用你的"虚拟"ostream Stream/File做任何你想做的事情.
小智 6
有一种更简单的方法:
from django.core.files.base import ContentFile
uploaded_zip = zipfile.ZipFile(uploaded_file, 'r') # ZipFile
for filename in uploaded_zip.namelist():
with uploaded_zip.open(filename) as f: # ZipExtFile
my_django_file = ContentFile(f.read())
Run Code Online (Sandbox Code Playgroud)
使用此功能,您可以将上传到内存的文件直接转换为django文件.有关更完整的示例,假设您要将zip中的一系列图像文件上载到文件系统:
# some_app/models.py
class Photo(models.Model):
image = models.ImageField(upload_to='some/upload/path')
...
# Upload code
from some_app.models import Photo
for filename in uploaded_zip.namelist():
with uploaded_zip.open(filename) as f: # ZipExtFile
new_photo = Photo()
new_photo.image.save(filename, ContentFile(f.read(), save=True)
Run Code Online (Sandbox Code Playgroud)