0

I have a django blog and want to download a backup zipfile with all the entries. The blog post text content is stored in the database.

I have written this code with the goal of trying to get the zipfile to save a bunch of .txt files in the main zip directory, but all this code does is outputs a single corrupted zip file. It cannot be unzipped but for some reason it can be opened in Word and it shows all of the blog post text mashed up.

def download_backups(request):
    zip_filename = "test.zip"
    s = BytesIO()
    zf = zipfile.ZipFile(s, "w")
    blogposts = Blog.objects.all()
    for blogpost in blogposts:
        filename = blogpost.title + ".txt"
        zf.writestr(filename, blogpost.content)
    resp = HttpResponse(s.getvalue())
    resp['Content-Disposition'] = 'attachment; filename=%s' % zip_filename
    return resp

Any help is appreciated.

megawatt
  • 5
  • 1

1 Answers1

0

Based on this answer to another question, you may be having an issue with the read mode. You'll also need to call zf.close(), either explicitly or implicitly, before the file will actually be complete.

I think there's a simpler way of handling this using a temporary file, which should have the advantage of not needing to fit all of the file's contents in memory.

from tempfile import TemporaryFile
from zipfile import ZipFile


with TemporaryFile() as tf:
    with ZipFile(tf, mode="w") as zf:
        zf.writestr("file1.txt", "The first file")
        zf.writestr("file2.txt", "A second file")
    tf.seek(0)
    print(tf.read())

The with blocks here will result in your temp file going out of scope and being deleted, and zf.close being called implicitly before you attempt to read the file.

If the goal here is just to back up the data rather than using this specific format, though, I'd suggest using the built-in dumpdata management command. You can call it from code if you want to serve the results through a view like this.

kungphu
  • 4,592
  • 3
  • 28
  • 37