Невозможно получить доступ к FileResponse.streaming_content и вернуть FileRespone - PullRequest
0 голосов
/ 07 октября 2019

Ситуация:

  • Я могу вернуть HTTP-ответ, содержащий файл.
  • Я могу вернуть HTTP-ответ, содержащий хэш файла.
  • Я не могу вернуть файл и хэш одновременно.

При попытке получить доступ к свойству streaming_content объекта Django FileResponse, HTTP-запрос истекает ине может вернуться.

Этот код правильно возвращает запрошенный файл.

class DownloadFile(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request):

        try:
            user = request.user
            most_recent_report = Reports.objects.filter(user_id=user).latest("created_date")
            most_recent_report_filepath = settings.BASE_DIR + most_recent_report.filepath

            filename = 'report.pbf'
            response = FileResponse(request, open(most_recent_report_filepath, 'rb'), content_type='application/json')
            response['content-disposition'] = 'attachment; filename="%s"' % filename

            return response

        except Exception as e:
            return Response({'status': str(e)}, content_type="application/json")

Этот код правильно возвращает хэш SHA256 запрошенного файла.

class DownloadFile(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request):

        try:
            user = request.user
            most_recent_report = Reports.objects.filter(user_id=user).latest("created_date")
            most_recent_report_filepath = settings.BASE_DIR + most_recent_report.filepath

            filename = 'report.pbf'
            response = FileResponse(request, open(most_recent_report_filepath, 'rb'), content_type='application/json')
            response['content-disposition'] = 'attachment; filename="%s"' % filename

            h = hashlib.sha256()
            partial_data = b''.join(response.streaming_content)
            h.update(partial_data)
            partial_hash = h.hexdigest()

            return Response({'status': str(partial_hash)})

        except Exception as e:
            return Response({'status': str(e)}, content_type="application/json")

Этот код не может ничего вернуть, и время ожидания истекло.

class DownloadFile(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request):

        try:
            user = request.user
            most_recent_report = Reports.objects.filter(user_id=user).latest("created_date")
            most_recent_report_filepath = settings.BASE_DIR + most_recent_report.filepath

            filename = 'report.pbf'
            response = FileResponse(request, open(most_recent_report_filepath, 'rb'), content_type='application/json')
            response['content-disposition'] = 'attachment; filename="%s"' % filename

            h = hashlib.sha256()
            partial_data = b''.join(response.streaming_content)
            h.update(partial_data)
            partial_hash = h.hexdigest()

            response['version'] = str(partial_hash)

            return response

        except Exception as e:
            return Response({'status': str(e)}, content_type="application/json")

Есть ли какой-то способ обойти и файл, и доступ к streaming_contentв то же время?


РЕДАКТИРОВАТЬ:

Одним из возможных решений, которые я придумал, было создание двух объектов FileResponse. С первым объектом я могу получить доступ к streaming_content и вычислить хэш файлов. Со вторым объектом я могу прикрепить хеш и вернуть объект. Это решение не очень хорошее, так как мне нужно загрузить файл дважды. Для больших файлов это ужасно неэффективно. Любые предложения приветствуются.

class DownloadFile(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request):

        try:
            user = request.user
            most_recent_report = Reports.objects.filter(user_id=user).latest("created_date")
            most_recent_report_filepath = settings.BASE_DIR + most_recent_report.filepath

            filename = 'report.pbf'
            response1 = FileResponse(request, open(most_recent_report_filepath, 'rb'), content_type='application/json')

            h = hashlib.sha256()
            partial_data = b''.join(response1.streaming_content)
            h.update(partial_data)
            partial_hash = h.hexdigest()

            response2 = FileResponse(request, open(most_recent_report_filepath, 'rb'), content_type='application/json')
            response2['content-disposition'] = 'attachment; filename="%s"' % filename
            response2['version'] = str(partial_hash)

            return response2

        except Exception as e:
            return Response({'status': str(e)}, content_type="application/json")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...