用Django生成可下载文件

98 投票
7 回答
94787 浏览
提问于 2025-04-15 11:49

有没有办法创建一个压缩文件,然后提供下载,但又不把这个文件保存到硬盘上?

7 个回答

11

为什么不直接做一个tar文件呢?像这样:

def downloadLogs(req, dir):
    response = HttpResponse(content_type='application/x-gzip')
    response['Content-Disposition'] = 'attachment; filename=download.tar.gz'
    tarred = tarfile.open(fileobj=response, mode='w:gz')
    tarred.add(dir)
    tarred.close()

    return response
28

创建一个临时文件会让你更开心。这可以节省很多内存。当同时有一两个用户在使用时,你会发现节省内存是非常非常重要的。

不过,你也可以写入一个 StringIO 对象。

>>> import zipfile
>>> import StringIO
>>> buffer= StringIO.StringIO()
>>> z= zipfile.ZipFile( buffer, "w" )
>>> z.write( "idletest" )
>>> z.close()
>>> len(buffer.getvalue())
778

这个“缓冲区”对象就像一个文件,里面有一个778字节的ZIP压缩包。

118

要开始下载,你需要设置一个叫做 Content-Disposition 的头信息:

from django.http import HttpResponse
from wsgiref.util import FileWrapper

# generate the file
response = HttpResponse(FileWrapper(myfile.getvalue()), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=myfile.zip'
return response

如果你不想把文件保存到硬盘上,可以使用 StringIO

import cStringIO as StringIO

myfile = StringIO.StringIO()
while not_finished:
    # generate chunk
    myfile.write(chunk)

你还可以选择设置一个叫做 Content-Length 的头信息:

response['Content-Length'] = myfile.tell()

撰写回答