DRF not supporting multiple renderer_classes

1.3k Views Asked by At

I'm using Django 2.x and DRF

I have a view which returns the binary data in different formats like pdf, eps, etc.

To return binary response, I have set the renderer_classes property and my view is

class DownloadQRCode(APIView):
    renderer_classes = (PdfFileRenderer, EPSRenderer,)

    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)

        name = serializer.validated_data.get('name')
        data = serializer.validated_data.get('data')

        mimetype = None

        if data and name:

            imgarr = name.rsplit('.', 1)

            if len(imgarr) == 2:
                name, format = imgarr

                if format == 'pdf':
                    data = str(unquote(data, encoding='utf-8'))
                    data, mimetype = generate_data_cairo(data, format)
                if format == 'eps':
                    data = str(unquote(data, encoding='utf-8'))
                    data, mimetype = svg_2_eps(data)

                if data and mimetype:

                    response = Response(data=data, content_type=mimetype)

                    response['Content-Disposition'] = 'attachment; filename=%s' % "-".join(name.split())

                    return response
                else:
                    return Response(status=status.HTTP_400_BAD_REQUEST, data='Either data or mime type was missing')
            else:
                return Response(status=status.HTTP_400_BAD_REQUEST, data='filename does not contain formatInfo')
        else:
            return Response(status=status.HTTP_400_BAD_REQUEST)

I have two renderer_classes

PdfFileRenderer

class PdfFileRenderer(BaseRenderer):
    media_type = 'application/octet-stream'
    format = None
    charset = None
    render_style = 'binary'

    def render(self, data, media_type=None, renderer_context=None):
        return data

and EPSRenderer

class EPSRenderer(BaseRenderer):
    media_type = 'image/eps'
    format = None
    charset = 'utf-8'
    render_style = 'binary'

    def render(self, data, accepted_media_type=None, renderer_context=None):
        return data

Using any one of them is working fine for that file type. But I want to use both so that appropriate renderer can be used depending on the file requested.

But, this is giving error and only first in the set is working.

1

There are 1 best solutions below

0
Anuj TBE On

Agree with @Nafees

Got it resolved by overriding get_renderer() method.

def get_renderer(self):

    imgarr = name.rsplit('.', 1)
    name, format = imgarr

    if format == 'pdf':
       return [BinaryRenderer()]
    if format == 'eps':
       return [EPSRenderer()]

    return super().get_renderer()