Search code examples
pythondjangofile

Django - Create A Zip of Multiple Files and Make It Downloadable


Possible Duplicate:
Serving dynamically generated ZIP archives in Django

(Feel free to point me to any potential duplicates if I have missed them)

I have looked at this snippet: http://djangosnippets.org/snippets/365/

and this answer:

but I wonder how I can tweak them to suit my need: I want multiple files to be zipped and the archive available as a download via a link (or dynamically generated via a view). I am new to Python and Django so I don't know how to go about it.

Thank in advance!


Solution

  • I've posted this on the duplicate question which Willy linked to, but since questions with a bounty cannot be closed as a duplicate, might as well copy it here too:

    import os
    import zipfile
    import StringIO
    
    from django.http import HttpResponse
    
    
    def getfiles(request):
        # Files (local path) to put in the .zip
        # FIXME: Change this (get paths from DB etc)
        filenames = ["/tmp/file1.txt", "/tmp/file2.txt"]
    
        # Folder name in ZIP archive which contains the above files
        # E.g [thearchive.zip]/somefiles/file2.txt
        # FIXME: Set this to something better
        zip_subdir = "somefiles"
        zip_filename = "%s.zip" % zip_subdir
    
        # Open StringIO to grab in-memory ZIP contents
        s = StringIO()
    
        # The zip compressor
        zf = zipfile.ZipFile(s, "w")
    
        for fpath in filenames:
            # Calculate path for file in zip
            fdir, fname = os.path.split(fpath)
            zip_path = os.path.join(zip_subdir, fname)
    
            # Add file, at correct path
            zf.write(fpath, zip_path)
    
        # Must close zip for all contents to be written
        zf.close()
    
        # Grab ZIP file from in-memory, make response with correct MIME-type
        resp = HttpResponse(s.getvalue(), mimetype = "application/x-zip-compressed")
        # ..and correct content-disposition
        resp['Content-Disposition'] = 'attachment; filename=%s' % zip_filename
    
        return resp