Во время разработки часто требуется сделать хоть какую-то раздачу статичных файлов в django. Описанный далее способ можно применять только во время разработки, но никак не на продуктовой среде (много уязвимостей и медленно раздаёт файлы). Но зато он хоть как-то позволяет сделать раздачу файлов.
Пусть у приложения "app" будут сохраняться загруженные файлы в "app/uploads/". Тогда для раздачи этих файлов делаем следующее
Добавляем в app/urls.py:
urlpatterns = [
...
path('uploads/<str:filepath>', views.download_file)
]
Добавляем в app/views.py:
def download_file(request, filepath):
import mimetypes
import os
file_path = 'app/uploads/' + filepath
if os.path.exists(file_path):
mime_type, _ = mimetypes.guess_type(file_path)
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(), content_type=mime_type)
response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
return response
raise Http404
Теперь в моделях app/models.py надо указывать в параметре upload_to путь к папке с загрузками:
models.FileField(upload_to='app/uploads/')
Заметка: если у приложения будет монолитная архитектура, то пакуйте в докер контейнер django, nginx и gunicorn одновременно.
Идеальное решение для раздачи статики с сайта - это сделать отдельный сервер с файлами на поддомене. Но такая роскошь нужна довольно редко, достаточно монолитной архитектуры, где всё в одной коробке.
P.S.
Описанный выше способ подойдёт в качестве заготовки даже для работы в продуктовой среде, если нужно позволить загрузки только определённым авторизованными пользователями (например, при продаже электронного контента). Но стоит ограничить список возможных путей файлов для скачивания и добавить проверку разрешения на скачивание (или вообще выдавать файлы по какому-то id, а не пути).