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

查看:27
本文介绍了如何使用 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.

我该怎么做?我试过 this 但它给出了一个错误 <django.http.HttpResponse对象在 0x7f7d32ffafd0>不是 JSON 可序列化的.

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 的混合,这不是您要查找的内容,或者将返回一个巨型 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

另一种方法是将 PDF 编码为文本,使用类似 base64 编码.这将显着增加您的响应大小,但它可以让您毫无问题地使用 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天全站免登陆