[PYTHON] Djnago Memo Set Japanese to filename of Content-Disposition

2020/2/7 postscript A colleague pointed out and made the following corrections: bow:

--url encode the value of filename =

Purpose

I want to download a file with a Japanese file name (file name including multibyte character string) in response to the request. It's common to all web apps, not just Django.

environment

Django: 1.10.xx Python: 3 series

Content-Diposition

When downloading a file via http, you need to set the Content-Disposition field of the response. Here you can specify the file name at the time of download and whether to execute the download immediately.

Content-Type='application/pdf'
Content-Disposition: filename="hogehoge.pdf";

Django View

If you make the above settings in Django's View, it will look like this.

The point is that instead of setting the file name normally, the URL-encoded file name is set. I feel that I can go when I can go with this setting, but the characters are garbled depending on the browser.

view.py


from django.views.generic import View
import urllib.parse

class DownloadTestView(View):
    def get(self, request):
        test_filename = 'test.pdf'
        response = HttpResponse(status=200, content_type='application/pdf')
        """
~ Somehow PDF generation processing ~
        """
        response['Content-Disposition'] = "filename='{}'".format(urllib.parse.quote(test_filename))
        return response

solution

The fact that the behavior differs depending on the browser means that the processing should be changed depending on the browser. If you look at the User-Agent field of the http request, you can see the name of the browser you are accessing, so the craftsman puts his heart into the if statement for each browser ...

Even if you don't do something like that, it seems that you can handle it by setting the filename * field of Content-Diposition.

Reference: [Download file name, fight against garbled characters](http://negiblog.hatenablog.com/entry/2015/06/19/%25e3%2583%2580%25e3%2582%25a6%25e3%2583%25b3 % 25e3% 2583% 25ad% 25e3% 2583% 25bc% 25e3% 2583% 2589% 25e3% 2583% 2595% 25e3% 2582% 25a1% 25e3% 2582% 25a4% 25e3% 2583% 25ab% 25e5% 2590% 258d% 25e3 % 2580% 2581% 25e6% 2596% 2587% 25e5)

Content-Disposition = filename = "filename"; filename * = UTF-8'' URL-encoded filename;

This is quite so.

Conclusion

Finally, when I put it in Django's view, it looks like this.

view.py


from django.views.generic import View
import urllib.parse

class DownloadTestView(View):
    def get(self, request):
        test_filename = 'test.pdf'
        quoted_filename = urllib.parse.quote(test_filename)

        #Incidentally, RFC6266 compliant("attachment"Add)
        # https://tools.ietf.org/html/rfc6266#section-5
        response = HttpResponse(status=200, content_type='application/pdf')
        """
~ Somehow PDF generation processing ~
        """
        response['Content-Disposition'] = "attachment;  filename='{}'; filename*=UTF-8''{}".format(quoted_filename, quoted_filename)
        return response

By setting the URL-encoded file name in filename *, it can be used with various browsers. We have confirmed the operation on Chrome, Firefox, and Safari.

Recommended Posts

Djnago Memo Set Japanese to filename of Content-Disposition
How to set the server time to Japanese time
Set the range of active strips to the preview range
[Python] Memo to translate Matplotlib into Japanese [Windows]
[Introduction to cx_Oracle] (5th) Handling of Japanese data
Procedure to set hydrogen of atom (virtual environment)
A memo connected to HiveServer2 of EMR with python
A memo of how to use AIST supercomputer ABCI
A memo to visually understand the axis of pandas.Panel
Memo of how to use properly when combining pandas.DataFrame
Memo of deploying Django × Postgresql on Docker to Heroku
[Blender] How to dynamically set the selection of EnumProperty
Set the specified column of QTableWidget to ReadOnly StyledItemDelegate