Проблема в том, что вы пытаетесь вернуть смесь JSON и PDF, которая либо не является тем, что вы ищете, либо собирается вернуть гигантский base64-кодированный ответ. PDF - это двоичный формат, а JSON - текстовый формат, и вы не можете их хорошо смешивать.
В представлении DRF вы можете напрямую вернуть ответ Django, который вы уже создаете (HttpResponse
), и DRF передаст его и пропустит средства визуализации. Это полезно в таких случаях, поскольку это позволяет вам возвращать двоичный ответ, такой как изображение или PDF, не беспокоясь о том, что слой рендеринга DRF вызывает проблемы.
@detail_route(methods=['get'])
def fetch_report(self, request, *args, **kwargs):
short_report = open("somePdfFile", 'rb')
response = HttpResponse(FileWrapper(short_report), content_type='application/pdf')
return response
Альтернативой для кодирования PDF в виде текста, используя что-то вроде base64 encoding. Это значительно увеличит ваши размеры ответов, но это позволит вам без проблем использовать слой рендеринга DRF.
@detail_route(methods=['get'])
def fetch_report(self, request, *args, **kwargs):
import base64
short_report = open("somePdfFile", 'rb')
report_encoded = base64.b64encode(short_report.read())
return Response({'detail': 'this works',
'report': report_encoded})
Но маршрут я бы рекомендовал здесь, чтобы сгенерировать PDF и сохранить его в любом вашем хранилище медиа, или альтернативного частном месте, а также обеспечить прямую ссылку на него в своем ответе. Таким образом, вам не нужно беспокоиться о проблемах с кодировкой, не нужно напрямую возвращать PDF-файл, и вам не нужно беспокоиться о прямом обслуживании PDF-файла.
Вы не можете сделать это за один шаг. Либо ответ в формате PDF, либо ответ JSON. Вы можете кодировать содержимое pdf в строку JSON, но это будет (выполнимо, но) трудно заставить его сохранить на клиенте. Обычно такие вещи выполняются в двухэтапном процессе: сначала получите ответ JSON, затем, если это удалось, запросите фактический файл. – spectras