Django загружает двоичный файл из FastAPI (URL-адрес, указанный MinIO), но файл поврежден и загружен с неправильным именем
Я использую Django (интерфейс) и Fast API (серверная часть) с MinIO в качестве хранилища файлов. Мои настройки:
- Быстрый API генерирует предварительно заданный MinIO download_url для файла.
- Django извлекает метаданные с помощью FastAPI, затем загружает файл с помощью requests.get(download_url, stream=True) и возвращает его с помощью StreamingHttpResponse.
Вот мой вид Django для загрузки файла:
from django.http import StreamingHttpResponse, Http404
from django.utils.encoding import smart_str
from urllib.parse import quote
import requests
def download_file(request, file_id):
print(f'file_id = {file_id}')
try:
url = f"http://89.150.34.163:8000/api/v1/student/download/{file_id}"
response = requests.get(url)
if response.status_code != 200:
raise Http404("Файл не найден")
json_data = response.json()
download_url = json_data.get("download_url")
original_filename = json_data.get("original_filename", f"file_{file_id}")
print(f'filename: {original_filename}')
if not download_url:
raise Http404("Ссылка на скачивание отсутствует")
file_response = requests.get(download_url, stream=True)
if file_response.status_code != 200:
raise Http404("Ошибка при скачивании файла")
filename_ascii = smart_str(original_filename)
filename_utf8 = quote(original_filename)
response = StreamingHttpResponse(
streaming_content=file_response.iter_content(chunk_size=8192),
content_type=file_response.headers.get("Content-Type", "application/octet-stream")
)
response['Content-Disposition'] = (
f'attachment; filename="{filename_ascii}"; '
f"filename*=UTF-8''{filename_utf8}"
)
return response
except Exception as e:
print(f"Ошибка при скачивании: {e}")
raise Http404("Ошибка при скачивании файла")
Когда я загружаю файл через браузер (вставляя download_url напрямую), он работает отлично — корректное имя файла и содержимое.
Но когда я загружаю его через Django, у файла оказывается поврежденное имя (например, загруженное, загруженное и т.д.). Файл .docx поврежден и не может быть открыт в MS Word (даже если размер в байтах указан правильно — например, 23526 байт).
Я попытался использовать smart_strand quote() для обработки имен файлов в Юникоде/кириллице и проверки того, что FastAPI возвращает правильные значения download_url и original_filename.
Есть какие-нибудь предложения? Есть ли лучший способ проксировать файл с предварительно подписанного URL-адреса MinIO через Django без повреждения?