Is it possible to make a zip archive and offer it to download, but still not save a file to the hard drive?
Yes, you can use the zipfile module, zlib module or other compression modules to create a zip archive in memory. You can make your view write the zip archive to the HttpResponse
object that the Django view returns instead of sending a context to a template. Lastly, you'll need to set the mimetype to the appropriate format to tell the browser to treat the response as a file.
You'll be happier creating a temporary file. This saves a lot of memory. When you have more than one or two users concurrently, you'll find the memory saving is very, very important.
You can, however, write to a StringIO object.
>>> import zipfile
>>> import StringIO
>>> buffer= StringIO.StringIO()
>>> z= zipfile.ZipFile( buffer, "w" )
>>> z.write( "idletest" )
>>> z.close()
>>> len(buffer.getvalue())
778
The "buffer" object is file-like with a 778 byte ZIP archive.
To trigger a download you need to set Content-Disposition
header:
from django.http import HttpResponse
from django.core.servers.basehttp import FileWrapper
# generate the file
response = HttpResponse(FileWrapper(myfile), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=myfile.zip'
return response
If you don't want the file on disk you need to use StringIO
import cStringIO as StringIO
myfile = StringIO.StringIO()
while not_finished:
# generate chunk
myfile.write(chunk)
Optionally you can set Content-Length
header as well:
response['Content-Length'] = myfile.tell()