3

I want to download a file with Django's httpresponse method. The name of the file has some special characters, like Chinese. I can download the file with the following code, but the file name appears as "%E6%B8%B8%E6%88%8F%E6%B5%8F%E8%A7%88%E5%99%A8%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.jpg".

Could anyone tell me how to convert the file name?

response = HttpResponse(attachment.file, content_type='text/plain',mimetype='application/octet-stream')

response['Content-Disposition'] = "attachment; filename="+urlquote(filename)
return response

Edit:

Another problem comes out when using smart_str, the file name can be displayed normally in Firefox and Chrome, but not in IE: in IE it's still displaying some unknown characters. Does anyone know how to fix this problem?

Thanks in advance!

---solved by use urlquote and smart_str differently in IE and other browsers.

dda
  • 6,030
  • 2
  • 25
  • 34
Angelia
  • 333
  • 1
  • 3
  • 9

4 Answers4

2

The following code works for me to solve your problem.

from django.utils.encoding import escape_uri_path

response = HttpResponse(attachment.file, content_type='text/plain',mimetype='application/octet-stream')

response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(filename))
return response
merenptah
  • 476
  • 4
  • 15
  • 1
    Are you saying, "the following code works for me to solve your problem"? If so, can you explain how so the OP can apply it to their issue? – sgress454 Oct 10 '15 at 16:39
2

I think it may have something to do with Encoding Translated Strings

Try this:

    from django.utils.encoding import smart_str, smart_unicode
    response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(filename)
    return response
darren
  • 18,845
  • 17
  • 60
  • 79
0

There is no interoperable way to encode non-ASCII names in Content-Disposition. Browser compatibility is a mess.

/real_script.php/fake_filename.doc
/real_script.php/mot%C3%B6rhead   # motörhead

please look at https://stackoverflow.com/a/216777/1586797

Community
  • 1
  • 1
bronze man
  • 1,470
  • 2
  • 15
  • 28
0

Thanks to bronze man and Kronel, I have come to an acceptable solution to this problem:

urls.py:

url(r'^customfilename/(?P<filename>.+)$', views.customfilename, name="customfilename"),

views.py:

def customfilename(request, *args, filename=None, **kwds):
    ...
    response = HttpResponse(.....)
    response['Content-Type'] = 'your content type'
    return response

your_template.html (links to the view providing the file)

<a href="customfilename/{{ yourfancyfilename|urlencode }}.ext">link to your file</a>

Please note that filename doesn't really need to be a parameter. However, the above code will let your function know what it is. Useful if you handle multiple different Content-Types in the same function.

Community
  • 1
  • 1
velis
  • 8,747
  • 4
  • 44
  • 64