40 lines
1.6 KiB
Python
40 lines
1.6 KiB
Python
import os
|
|
import mimetypes
|
|
from django.http import HttpResponse, Http404
|
|
from django.conf import settings
|
|
from django.views.generic import View
|
|
from django.utils.decorators import method_decorator
|
|
from django.views.decorators.cache import cache_control
|
|
|
|
|
|
@method_decorator(cache_control(max_age=31536000), name='dispatch')
|
|
class MediaFileView(View):
|
|
"""
|
|
Обслуживание медиа файлов в production режиме.
|
|
"""
|
|
|
|
def get(self, request, file_path):
|
|
# Полный путь к файлу
|
|
full_path = os.path.join(settings.MEDIA_ROOT, file_path)
|
|
|
|
# Проверка безопасности - файл должен находиться в MEDIA_ROOT
|
|
if not os.path.abspath(full_path).startswith(os.path.abspath(settings.MEDIA_ROOT)):
|
|
raise Http404("Файл не найден")
|
|
|
|
# Проверка существования файла
|
|
if not os.path.exists(full_path) or not os.path.isfile(full_path):
|
|
raise Http404("Файл не найден")
|
|
|
|
# Определение MIME типа
|
|
content_type, _ = mimetypes.guess_type(full_path)
|
|
if content_type is None:
|
|
content_type = 'application/octet-stream'
|
|
|
|
# Чтение файла и возврат ответа
|
|
try:
|
|
with open(full_path, 'rb') as f:
|
|
response = HttpResponse(f.read(), content_type=content_type)
|
|
response['Content-Length'] = os.path.getsize(full_path)
|
|
return response
|
|
except Exception:
|
|
raise Http404("Ошибка чтения файла") |