Define renderer class dynamically in Django view function

Viewed 149

How can I define the renderer class inside the Djanog old api_view function depending on some condition? To have something like this:

@api_view(['GET'])
def can_render_2_things(request):
    if some_comdition:
       renderer_classes = [PDFRenderer]
    else:
       renderer_classes = [JSONRenderer]
2 Answers

From Django docs you can use different responses objects:

from django.http import FileResponse, JsonResponse
@api_view(['GET'])
def can_render_2_things(request):
    if some_comdition:
       response = FileResponse(open('myfile.png', 'rb'))
    else:
       response = JsonResponse({'foo': 'bar'}, encoder=myJsonEncoder)

You can set the attributes accepted_renderer and accepted_media_type on the request yourself if the renderer_classes list you want to set contains only one renderer class. This will cause the correct renderer to be used:

@api_view(['GET'])
def can_render_2_things(request):
    if some_comdition:
       request.accepted_renderer = PDFRenderer
       request.accepted_media_type = PDFRenderer.media_type
    else:
       request.accepted_renderer = JSONRenderer
       request.accepted_media_type = JSONRenderer.media_type

But this is not very useful if you want to set more renders, I would advice you to simply move to using class based views instead of function based ones and use the APIView:

from rest_framework.views import APIView


class CanRender2Things(APIView):
    def get(self, request, format=None):
        if some_comdition:
            self.renderer_classes = [PDFRenderer]
        else:
            self.renderer_classes = [JSONRenderer]
Related