DjangoでCSVを出力する
このドキュメントでは、Djangoビューを使用してCSV(カンマ区切り値)を動的に出力する方法について説明します。 これを行うには、PythonCSVライブラリまたはDjangoテンプレートシステムのいずれかを使用できます。
PythonCSVライブラリの使用
Pythonには、CSVライブラリcsv
が付属しています。 Djangoで使用するための鍵は、csv
モジュールのCSV作成機能がファイルのようなオブジェクトに作用し、Djangoの HttpResponse オブジェクトがファイルのようなオブジェクトであるということです。
次に例を示します。
コードとコメントは自明である必要がありますが、いくつか言及する価値があります。
- 応答は、特別なMIMEタイプ text / csv を取得します。 これにより、ドキュメントがHTMLファイルではなくCSVファイルであることがブラウザに通知されます。 これをオフのままにすると、ブラウザはおそらく出力をHTMLとして解釈し、ブラウザウィンドウに醜い恐ろしいgobbledygookが表示されます。
- 応答は、CSVファイルの名前を含む追加の
Content-Disposition
ヘッダーを取得します。 このファイル名は任意です。 好きなように呼んでください。 「名前を付けて保存…」ダイアログなどでブラウザによって使用されます。 csv.writer
の最初の引数としてresponse
を渡すことにより、CSV生成APIにフックできます。csv.writer
関数はファイルのようなオブジェクトを想定しており、 HttpResponse オブジェクトは適切です。- CSVファイルの各行について、
writer.writerow
を呼び出し、 iterable を渡します。 - CSVモジュールが引用符を処理するため、引用符やカンマを含む文字列をエスケープする必要はありません。
writerow()
を生の文字列に渡すと、正しい処理が実行されます。
大きなCSVファイルのストリーミング
非常に大きな応答を生成するビューを処理する場合は、代わりにDjangoの StreamingHttpResponse の使用を検討することをお勧めします。 たとえば、生成に時間がかかるファイルをストリーミングすることで、サーバーが応答を生成している間にタイムアウトした可能性のある接続をロードバランサーがドロップするのを回避できます。
この例では、Pythonジェネレーターを最大限に活用して、大きなCSVファイルのアセンブリと送信を効率的に処理します。
テンプレートシステムの使用
または、 Djangoテンプレートシステムを使用してCSVを生成することもできます。 これは、便利なPython csv
モジュールを使用するよりも低レベルですが、完全を期すためにソリューションをここに示します。
ここでの考え方は、アイテムのリストをテンプレートに渡し、テンプレートに:ttag: `for` ループでコンマを出力させることです。
上記と同じCSVファイルを生成する例を次に示します。
この例と前の例の唯一の違いは、この例ではCSVモジュールの代わりにテンプレートの読み込みを使用していることです。 content_type='text/csv'
などの残りのコードは同じです。
次に、次のテンプレートコードを使用して、テンプレートmy_template_name.txt
を作成します。
この短いテンプレートは、指定されたデータを繰り返し処理し、各行のCSV行を表示します。 :tfilter: `addslashes` テンプレートフィルターを使用して、引用符に問題がないことを確認します。
その他のテキストベースの形式
ここではCSVに固有のものはあまりなく、特定の出力形式のみであることに注意してください。 これらの手法のいずれかを使用して、夢のようなテキストベースの形式を出力できます。 同様の手法を使用して、任意のバイナリデータを生成することもできます。 例については、 Django を使用したPDFの出力を参照してください。