Django downloads binary file from FastAPI (MinIO presigned URL), but the file is corrupted and downloaded with wrong name

I'm using Django (frontend) and FastAPI (backend) with MinIO as file storage. My setup:

  • FastAPI generates a presigned MinIO download_url for the file.
  • Django fetches metadata via FastAPI, then downloads the file using requests.get(download_url, stream=True) and returns it with StreamingHttpResponse.

Here is my Django view for downloading the file:

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("Ошибка при скачивании файла")

When I download the file via browser (pasting the download_url directly), it works perfectly — correct filename and contents.

But when I download it through Django the file has a corrupted name (e.g. download, загруженное, etc.). The .docx file becomes corrupted and can't be opened in MS Word (even though the byte size is correct — e.g., 23526 bytes).

I tried using smart_str and quote() to handle Unicode/cyrillic filenames and validating that FastAPI returns the correct download_url and original_filename.

Any suggestions? Is there a better way to proxy a file from a presigned MinIO URL through Django without corruption?

Вернуться на верх