0

Django 1.7, Python 3.4, windows apache 2.4.12 + wsgi

In my program, I generate some csv files and put them in a zip file. I would like to let the user download the zip file, either force download (after file is generated and render response) or a click of button (after display result, user has to click a button to download.)

Currently I am forcing them to download once the zip file is generated on the server.

I have referenced the following links and come up with my code below. But it is always give me this error "'charmap' codec can't decode byte 0x8d in position 80: character maps to " I tried to set it with utf-8 and ascii, and similar errors will be given.

referenced links:

Anyone know why am I getting this error and how to get this to work?

Thank you very much!

zip_filename = time.strftime("%Y%m%d") + ".zip"
with zipfile.ZipFile(zip_filename, mode='a', compression=zipfile.ZIP_DEFLATED) as zf:
    for s in sql_request:
        // generate csv files
        zf.write(csv_file)

// close zf

zip_file = open(zip_filename, 'r')
response = HttpResponse(zip_file, content_type='application/force-download')
response['Content-Disposition'] = 'attachment; filename="%s"' % 'foo.zip'
return response
Community
  • 1
  • 1
wolf97084
  • 270
  • 4
  • 22
  • Consider serving zip files using a dedicated web server like apache / nginx. This is extremely easy to do using `XSendfile` / `X-Accel-Redirect`. See this: http://stackoverflow.com/a/1158750/1268926 – Kedar Mar 06 '15 at 17:13
  • I want to point out, from your example, zipping is not useful. You should gzip-compress all output from your server anyways. It looks like there is only 1 csv file in the zip, so why bother? – beiller Mar 06 '15 at 21:20
  • @beiller There're more than one file I need to zip. How do you specify using gzip in python? I only see two compression options, one is zipfile.ZIP_DEFLATED and the other is zipfile.ZIP_STORED, which is more like archiving. – wolf97084 Mar 06 '15 at 21:35
  • @kedar Thank you for the link. I will check it out. No idea about how to setup nginx, but I will try. – wolf97084 Mar 06 '15 at 21:37
  • I'm not sure the configuration. Usually web servers send HTML documents GZIP compressed to save bandwidth. It should do the same sending the CSV file. It's usually done "behind the scenes". – beiller Mar 06 '15 at 22:04

1 Answers1

1

If you're on Windows, you might need to change your open line to include the b flag.

zip_file = open(zip_filename, 'rb')

Matt Cooper
  • 927
  • 9
  • 16
  • if I add 'b' as you suggested, it give me a programming error " relation "django_session" does not exist LINE 1: SELECT (1) AS "a" FROM "django_session" WHERE "django_sessio... ^ " What is this error? – wolf97084 Mar 06 '15 at 17:12
  • That error's coming from a very different place in Django and suggests that your database schema doesn't match your model definitions. You may need to make and apply migrations. – Matt Cooper Mar 06 '15 at 17:15
  • :) I got this error because in my setting I have set MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage' (I don't know why I have it nor do I really need it. I am a django newbie.) I commented it out and now it's working. Thank you. – wolf97084 Mar 06 '15 at 17:16
  • Great, glad to hear you found the issue :) – Matt Cooper Mar 06 '15 at 17:18