Django REST框架返回文件

22 投票
2 回答
35847 浏览
提问于 2025-04-18 18:12

我在views.py里有以下的视图 -

class FilterView(generics.ListAPIView):
    model = cdx_composites_csv

    def get(self, request, format=None):
        vendor = self.request.GET.get('vendor')
        filename = self.request.GET.get('filename')
        tablename = filename.replace(".","_")
        model = get_model(vendor, tablename)
        filedate = self.request.GET.get('filedate')        
        snippets = model.objects.using('markitdb').filter(Date__contains=filedate)
        serializer = cdx_compositesSerializer(snippets, many=True)
        if format == 'raw':
            zip_file = open('C:\temp\core\files\CDX_COMPOSITES_20140626.zip', 'rb')
            response = HttpResponse(zip_file, content_type='application/force-download')
            response['Content-Disposition'] = 'attachment; filename="%s"' % 'CDX_COMPOSITES_20140626.zip'
            return response

        else:
            return Response(serializer.data)

这个视图对于xml、json和csv格式都能很好地工作,但当我尝试使用raw格式时,它没有返回文件,而是给了我一个""detail": "Not found""的错误,这是什么原因呢?

我访问的URL如下 -

这是一个可以正常工作的json示例 -

http://dt-rpittom:8000/testfilter/?vendor=markit&filename=cdx_composites.csv&filedate=2014-06-26&format=json

这个请求应该返回一个可以下载的zip文件。

http://dt-rpittom:8000/testfilter/?vendor=markit&filename=cdx_composites.csv&filedate=2014-06-26&format=raw

2 个回答

13

试试使用 FileWrapper

from django.core.servers.basehttp import FileWrapper

...

if format == 'raw':
    zip_file = open('C:\temp\core\files\CDX_COMPOSITES_20140626.zip', 'rb')
    response = HttpResponse(FileWrapper(zip_file), content_type='application/zip')
    response['Content-Disposition'] = 'attachment; filename="%s"' % 'CDX_COMPOSITES_20140626.zip'
    return response
...

另外,我建议用 application/zip,而不是 application/force-download

24

我不知道为什么我必须这样做——可能是Django Rest Framework内部的一些原因,不允许在格式上添加自定义方法?

我只是把它改成了下面这样 -

if fileformat == 'raw':
    zip_file = open('C:\temp\core\files\CDX_COMPOSITES_20140626.zip', 'rb')
    response = HttpResponse(FileWrapper(zip_file), content_type='application/zip')
    response['Content-Disposition'] = 'attachment; filename="%s"' % 'CDX_COMPOSITES_20140626.zip'
    return response

然后在我的网址中使用这个新值,结果很好用。不过我还是想知道为什么我不能用格式来提供一个文件。

撰写回答