Django:マルチバイトファイル名でダウンロードさせる方法

  • 3
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

目的

リクエストに対してマルチバイトファイル名でファイルダウンロードさせる。

httpでファイルダウンロード

httpの決まり事として、ファイルをダウンロードさせたいときは、レスポンスに Content-Dispositionヘッダを含めれば良いことになっています。

Content-Disposition: attachment; filename="filename.txt"

Djangoの記述

下記で期待通り動きます。ただし、ファイル名がascii文字の場合です。

from django.http import HttpResponse
def index(request):
    content = 'body1'
    response = HttpResponse(content, content_type='text/plain')
    response['Content-Disposition'] = 'attachment; filename="filename.txt"'
    return response

マルチバイト文字の場合

単純に記述してみます。

response['Content-Disposition'] = 'attachment; filename="ファイル.txt"'

ヘッダは下記のようになります。UTF8-MIME-Base64のようにみえます。
実際、email.header.Headerを使ってエンコードしているようです。

Content-Disposition: =?utf-8?b?YXR0YWNobWVudDsgZmlsZW5hbWU9IuODleOCoeOCpOODqy50eHQi?=
  • これが正しい挙動なのか調べていませんが、とりあえず手元のWebブラウザではファイルをダウンロードするように解釈してくれないようです。

対応方法

ファイル名部分だけをURLエンコードしてセットします。

import urllib.parse
response['Content-Disposition'] = 'attachment; filename="{fn}"'.format(fn=urllib.parse.quote("ファイル.txt"))
  • ヘッダは下記のようになり、Webブラウザも期待通り、ファイルダウンロードレスポンスとして動作してくれます。
 Content-Disposition: attachment; filename="%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.txt"