I'm using django-rest-framework to create an endpoint which returns a PDF. However, when there is an error rendering the PDF, I want to return a JSON response. But DRF passes the data for the exception to my PDFRenderer class. How can I use JSONRenderer instead, only if there is an error?
class PDFRenderer(BaseRenderer):
""" DRF renderer for PDF binary content. """
media_type = 'application/pdf'
format = 'pdf'
charset = None
render_style = 'binary'
def render(self, data, media_type=None, renderer_context=None):
return bytes(data)
For example, when my view says raise PermissionDenied()
, because the authorized user does not have permission to view the requested PDF, DRF passes {'detail': 'You do not have permission to perform this action.'}
as the data
argument to PDFRenderer.render
.
Edit: I tried a custom exception handler but apparently you still have to run it through DRF's exception handler as well, which passes it to the PDFRenderer.
I found a way to do this with a custom exception handler after all:
from rest_framework.renderers import JSONRenderer
from rest_framework.views import exception_handler
def custom_exception_handler(exc, context):
""" Switch from PDFRenderer to JSONRenderer for exceptions """
if context['request'].accepted_renderer.format == 'pdf':
context['request'].accepted_renderer = JSONRenderer()
return exception_handler(exc, context)
It feels pretty hacky. Still hoping for a better answer.
If request is ok and file exists, I read it as bytes and pass it to Response, as custom renderer I use PDFRenderer as yours. If request isn't ok, I return json. My solution is to check if data is instance of bytes, if not, I just return bytes from valid json string, because render method should return bytes anyway
class PDFRenderer(BaseRenderer):
media_type = 'application/pdf'
format = 'pdf'
charset = None
render_style = 'binary'
def render(self, data, media_type=None, renderer_context=None):
if isinstance(data, bytes):
return data
data_to_response = json.dumps(data)
return bytes(data_to_response.encode('utf-8'))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With