A cheerful disposition

This is how you’re supposed to assign file names to files sent in a http response with Content-Disposition headers in Django, the way, the only way, nothing but the way, so help you God:


response['Content-Disposition'] = "attachment; filename*=UTF-8''{0}"
    .format(iri_to_uri(filename))

The actual problem is rather complicated, as up until just a couple years ago, browsers would mistreat this header left and right. Most examples I see on the net are actually either incorrect or only work properly for filenames limited to ascii or at least latin-1. While keeping non-ASCII characters out of filenames on principle might be a sensible policy, lots of people will not agree with you. The extant proper documentation is not terribly clear. Django throwing exceptions around made it even less clear.

Thankfully, I stumbled onto a well-organized page of test cases for header encodings across different browsers, which allowed me to figure out what exactly has been wrong with every other snippet I saw.

Basically, you both need to force-feed Django the url-encoded filename and write the header according to RFC 2231/5987 – either Django or a browser will complain unless you do both.