Django сломанный ответ с файловыми данными

В моем проекте я использую AWS S3 Bucket для медиа файлов. Проект содержит приложение media_app, которое обеспечивает get и post запросы к файлам в удаленном хранилище (все запросы проходят через сервер, поэтому media_app является своего рода прокси между фронтендом и AWS S3.

).

Сегодня я столкнулся с проблемой. Когда я пытаюсь получить медиа файл с AWS S3, Django корректно скачивает его с удаленного ведра, сохраняет в дир /tmp/, получает корректные метаданные ответа, но сам ответ не работает: он вызывает бесконечное состояние "in progress" ответа на стороне фронтенда (пробовал с Postman и Swagger). "В процессе" означает "фронтенд-приложение ждет, пока ответ будет получен", но на стороне бэкенда нет бесконечного цикла. Django может предоставить следующие ответы, даже если я использую тестовый сервер dev (это означает, что никакие рабочие не блокируются, потому что тестовый сервер django имеет только одного рабочего).

Информация о запросе и ответе (Django Silk): enter image description here

Есть часть моего представления, которая обеспечивает загрузку изображения:

from django.http import Http404, StreamingHttpResponse
from wsgiref.util import FileWrapper

class ImageDetailAPIView(DetailDownloadAPIView):
    queryset = Image.objects.filter(is_soft_deleted=False)\
                            .prefetch_related('thumbnails')
    serializer_class = ImageSerializer
    
    @swagger_auto_schema(responses=image_detail_responses)
    def get(self, request, *args, **kwargs):
        try:
            instance = self.get_object()
        except Http404:
            raise FileNotFoundException
        
        service = ImageDownloadService(instance)
        chunk_size = 8192
        file_path, status_code = service.download()
        if status_code == 200:
            response = StreamingHttpResponse(
                FileWrapper(open(file_path, 'rb'), chunk_size),
                content_type=instance.mime_type
            )
            response['Content-Length'] = instance.size
            response['Content-Disposition'] = "attachment; filename=%s" % instance.file_name
            return response
        raise UnexpectedCaseException(is_for_file=True)
Архитектура и код сервиса

не важны, так как я уже обнаружил, что он работает правильно: образ правильно идентифицировать в AWS и далее загрузить в /tmp/downloaded-file.webp. Замена StreamingHttpResponse на FileResponse не работает. Я тестировал все это с изображениями с форматами .png и .webp, и это все равно не работает.

Я решил проблему, используя этот пост (но не нашел причины ее возникновения):

  1. добавьте django.middleware.gzip.GZipMiddleware промежуточное ПО в переменную настроек проекта MIDDLEWARE.
  2. напишите подкласс для моего существующего FileWrapper (код ниже).

FixedFileWrapper:

class FixedFileWrapper(FileWrapper):
    def __iter__(self):
        self.filelike.seek(0)
        return self

Возможно, кто-то может объяснить мне причину моей проблемы?

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