Djangoではファイルのアップロード&ダウンロード機能が備わっていますが基本的には静的なものです。
たとえばユーザーによって保管場所を変えたりディレクトリを作成したり、アクセスされるタイミングによってダウンロードファイルを変えたりと動的にファイルの制御をしたいことがあるものです。
アップロード
HTML(必要な部分だけ)
<form id="upload" method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="upload">
<button type="submit">送信する</button>
</form>
これだけ。 csrf_tokenは地味に忘れがちなので要注意。
このformタグに enctype="multipart/form-data" が書かれていないとアップロードデータがNoneになってしまいますので超注意です。
pythonコード(必要な部分だけ)
def upload( request ):
#POSTリクエストのみ
if request.method == 'POST':
file = request.FILES.get('upload')
#ファイルが無い場合は処理しない
if file is not None:
#アップロードされた元のファイル名
name = file.name
#ファイルタイプ
type = file.content_type
#データのサイズ(単位はbyte)
size = file.size
#read() は一気に読み込むのでファイルが大きい場合はメモリリソースを食うので非推奨
#data = file.read()
if size < 1000000: #1MB以下のみ処理する
#実際に保存するディレクトリとファイル名
filename = '/dev/shm/testupload'
full_filename = os.path.join("media", "files", filename )
#書き込む
fout = open( full_filename, "wb+")
#chunks()でデータを分割しながら保存
for chunk in file.chunks():
fout.write( chunk )
fout.close()
こうするとアップロードされたファイルは任意の場所に任意のファイル名で(例の場合は /dev/shm/testupload )保存されます。
ダウンロード
HTML記述は無し。アクセスされたら即ダウンロード開始。
python(必要な部分のみ)
viewファイルで
from django.http import FileResponse
filename = 'ダウンロードファイル名.txt'
filepath = '/dev/shm/testupload'
return FileResponse( open(filepath, "rb") , as_attachment=True, filename=filename)
これだけ。
FileResponseをインポートすることと、as_attachmentがTrueだと即ダウンロード、Falseだとブラウザで開くという動きになるようです。
ダウンロードされるfilenameを任意で変更できるのは面白いですね。
例えば /download/photo にアクセスされると、「今日のおすすめの写真.jpg」ファイルがダウンロードされる。
というような使い方ができるわけですね^^。
<参考>
前の記事