如何使用django rest框架发送文件作为响应? [英] How do I use django rest framework to send a file in response?

查看:114
本文介绍了如何使用django rest框架发送文件作为响应?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要发送pdf文件和其他一些参数,以响应使用django rest框架进行的get API调用.

I need to send a pdf file and some other parameters in response to a get API call using django rest framework.

我该怎么办? 我尝试了,但它给出了错误<django.http.HttpResponse object at 0x7f7d32ffafd0> is not JSON serializable.

How can I do it? I tried this but it gives an error <django.http.HttpResponse object at 0x7f7d32ffafd0> is not JSON serializable.

@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({'detail': 'this works',
        'report': response})

推荐答案

这里的问题是,您正在尝试返回JSON和PDF的组合,这不是您要查找的内容,或者将返回一个 giant base64编码的响应. PDF是一种二进制格式,而JSON是一种文本格式,您无法真正将它们混合使用.

The problem here is that you are trying to return a mix of JSON and PDF, which either isn't what you are looking for or is going to return a giant base64-encoded response. PDF is a binary format and JSON is a text format, and you can't really mix them well.

在DRF视图中,您可以直接返回您已经似乎正在生成的Django响应(HttpResponse),并且DRF将通过它并跳过渲染器.在这种情况下这很有用,因为它使您可以返回二进制响应(例如图像或PDF),而不必担心DRF的渲染层会引起问题.

Within a DRF view you can directly return a Django response, which you already appear to be generating (the HttpResponse), and DRF will pass it through and skip the renderers. This is useful in cases like this, as it allows you to return a binary response such as an image or PDF without worrying about DRF's rendering layer causing problems.

@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

另一种方法是使用 base64编码之类的东西将PDF编码为文本.这将大大增加您的响应大小,但可以让您毫无问题地使用DRF的呈现层.

The alternative is to encode the PDF as text, using something like base64 encoding. This will dramatically increase your response sizes, but it will allow you to use DRF's rendering layer without problems.

@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提供服务.

But the route I would recommend here is to generate the PDF and store it in either your media storage, or an alternative private location, and provide a direct link to it in your response. This way you don't need to worry about the encoding issues, don't need to directly return the PDF, and don't need to worry about directly serving the PDF.

这篇关于如何使用django rest框架发送文件作为响应?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆