HOWTO · Django
Django でファイルをアップロードおよびダウンロードする
管理者がファイルをアップロードし、訪問者が添付ファイルとしてダウンロードできる Django のサンプルを作成します。
このページの内容
管理者がファイルをアップロードし、訪問者にダウンロードリンクを提供するには、アップロードを Django の FileField で保存し、選択したファイルを FileResponse で返します。このチュートリアルは Django 5.2 を対象とし、開発用にローカルのメディアストレージを使用します。ここで示す Django 連携は、提供されたランタイムでは実行されていません。
Django でファイルをアップロードおよびダウンロードする
django-admin startproject django_project でプロジェクトとアプリを作成し、manage.py を含むディレクトリから python manage.py startapp blog を実行します。django_project/settings.py のプロジェクトの INSTALLED_APPS に "blog.apps.BlogConfig" を追加します。
アップロードされたメディアは、CSS や JavaScript などの静的アセットとは分離されています。settings.py で MEDIA_URL = "/media/" と MEDIA_ROOT = BASE_DIR / "media" を設定します。MEDIA_ROOT はアップロードされたファイルのファイルシステム上の場所であり、MEDIA_URL はそれらを提供するために使用する URL プレフィックスです。アップロードは静的ファイル用ディレクトリの外に保管してください。
blog/models.py で、title = models.CharField(max_length=200) と file = models.FileField(upload_to="uploads/") を持つ UploadedFile モデルを定義します。管理画面で項目を識別できるよう、def __str__(self): return self.title を追加します。blog/admin.py で admin.site.register(UploadedFile) を使って登録します。モデルを作成したら、python manage.py makemigrations と python manage.py migrate を実行し、次に python manage.py createsuperuser で管理者を作成します。
blog/views.py に 2 つのビューを追加します。ホームビューはクエリセットを files コンテキスト値としてレンダリングできます: return render(request, "blog/home.html", {"files": UploadedFile.objects.all()})。ダウンロードビューでは、item = get_object_or_404(UploadedFile, pk=file_id) で行を検索し、FileResponse(item.file.open("rb"), as_attachment=True, filename=item.file.name.rsplit("/", 1)[-1]) を返します。FileResponse、get_object_or_404、UploadedFile をインポートします。このフレームワーク固有の Django 連携はここでは実行されていません。FileResponse はファイルをストリーミングし、as_attachment=True はブラウザにダウンロードするよう求めます。保存されたファイルは、設定されたストレージ内に引き続き存在している必要があります。
ビューは、パスの最後の要素をブラウザに提示する名前として使用します。この小さな Python の例は、保存されたアップロードパスを使ってそのファイル名のステップを示しています。
この例を実行します:
stored_name = "uploads/sample.mp3"
download_name = stored_name.rsplit("/", 1)[-1]
print(download_name)
sample.mp3
blog/urls.py で、ホームルートをホームビューに、"download/<int:file_id>/" を download_file に対応付け、後者に "download_file" という名前を付けます。プロジェクトの URL 設定から path("", include("blog.urls")) で blog.urls をインクルードします。blog/templates/blog/home.html で、各項目へのリンクをレンダリングします:
{% for item in files %}
<h2>{{ item.title }}</h2>
<a href="{% url 'download_file' item.pk %}">Download {{ item.title }}</a>
{% endfor %}
python manage.py runserver で開発サーバーを実行し、/admin/ でサインインして、タイトルと小さなサンプルファイルを持つ UploadedFile を追加します。ホームページにはそのタイトルが表示され、そのリンクを選択すると、そのファイルがダウンロード用の添付ファイルとして返されるはずです。このチュートリアルは想定される動作を説明するもので、観測されたランタイム出力は含まれていません。
ローカル開発サイトでは、settings.DEBUG が true のときに static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) をプロジェクトの URL パターンに追加することで、Django がアップロードされたメディアを提供できます。static は django.conf.urls.static からインポートします。このヘルパーは開発用であり、本番用のファイルサーバーではありません。本番環境では、Web サーバーまたはオブジェクトストレージでメディアを提供するよう設定し、各ファイルを公開するか、認証を必要とするかを決めてください。アップロードが非公開の場合は、MEDIA_URL を直接公開する代わりに、適切な権限チェックでダウンロードビューを保護します。アップロードを検証し、アプリケーションに合ったサイズとファイルタイプの制限を適用してください。