Как реализовать пользовательский рендерер в среде Django REST для экспорта PDF и Excel?

#django #excel #pdf #django-rest-framework

#джанго #превосходить #PDF #django-rest-фреймворк

Вопрос:

Я реализовал два пользовательских средства визуализации в среде django rest, которые экспортируют данные в формате Excel или PDF. Проблема в том, что я не могу задать имена файлов при создании ответа.

У меня есть следующие визуализаторы:

 # app/renderers.py import os import openpyxl import pdfkit import random  from django.template.loader import render_to_string  from rest_framework.renderers import BaseRenderer from rest_framework.response import Response  # for newer python, do the configuration for pdfkit config = pdfkit.configuration(wkhtmltopdf=r'path_to_bin/wkhtmltopdf')  class XLSXRenderer(BaseRenderer):  # ... code truncated   class PDFRenderer(BaseRenderer):  media_type = 'application/pdf'  format = 'pdf'  charset = 'utf-8'   def render(self, data, accepted_media_type=None, renderer_context=None):  if hasattr(data, 'items'):  for key, value in data.items():  if key == 'results':  html_string = render_to_string('user_mbe/EmployeeList.html', {'header': ('first_name', 'last_name', 'id_number', 'phone_number', 'email', 'job_title'), 'data': [tuple(x.values()) for x in value]})  result = pdfkit.from_string(html_string, output_path=False, configuration=config)   return result  return None  
 # app/views.py  from rest_framework.generics import ListCreateAPIView from rest_framework.permissions import IsAuthenticated from rest_framework.renderers import JSONRenderer  from .renderers import PDFRenderer, XLSXRenderer  from .models import Employee from .serializers.employee import EmployeeSerializer   class EmployeeAPIView(ListAPIView):  serializer_class = EmployeeSerializer  # Are these correct here?  renderer_classes = [PDFRenderer, XLSXRenderer, JSONRenderer]   def get_queryset(self):  return Employee.objects.filter(created_by=self.request.user)   def get(self, request, *args, **kwargs):  ?? super().get_paginated_response(request, *args, **kwargs)  ?? unable to set a file name here  return response  

Комментарии:

1. Вы только что задали вопрос и ответили на него в

2. Ха-ха, я просто никогда не видел, чтобы это делалось раньше, вот и все. Хотел убедиться, что мне ничего не мерещится

Ответ №1:

Импортируйте средства визуализации в свой views.py и вызовите метод списка суперкласса для вызова пользовательского средства визуализации. Как только вы получите ответ от своего .метод списка вы можете добавить заголовки для имени файла.

 # app/views.py # ...  class EmployeeAPIView(ListAPIView):  serializer_class = EmployeeSerializer  # The custom renderers go here  renderer_classes = [PDFRenderer, XLSXRenderer, JSONRenderer]   def get_queryset(self):  return Employee.objects.filter(created_by=self.request.user)   def get(self, request, *args, **kwargs):  # call .list method here to invoke the relevant renderer  # based on the request header accept or query param format type  response = super().list(request, *args, **kwargs)   if request.query_params.get("format", "").lower() == 'pdf':  response.headers = {'Content-Disposition': 'attachment; filename=employee_list.pdf'}  elif request.query_params.get("format", "").lower() == 'xlsx':  response.headers = {'Content-Disposition': 'attachment; filename=employee_list.xlsx'}   return response