Django zip files (create dynamic in-memory archives with Python’s zipfile)

Usually, Django should not be used to serve static files.

The reasoning here is that standard Web servers, such as Apache, lighttpd and Cherokee, are much more fine-tuned at serving static files than a Web application framework. - Django documentation

However, dynamic files are a different story. Say you want to wrap more than one file being generated on the fly from a form POST. In my case, I wanted to let the user download a zip archive of a few generated reports.

Using Python's zipfile it's easy to create the archive in-memory, without writing to disk. Then, serving that file as a zip content-type is easy in Django.

from StringIO import StringIO
from zipfile import ZipFile
from django.http import HttpResponse

def download(request, company_id):     
    in_memory = StringIO()
    zip = ZipFile(in_memory, "a")
    zip.writestr("file1.txt", "some text contents")
    zip.writestr("file2.csv", "csv,data,here")
    # fix for Linux zip files read in Windows
    for file in zip.filelist:
        file.create_system = 0    

    response = HttpResponse(mimetype="application/zip")
    response["Content-Disposition"] = "attachment;"    
    return response