提供.json文件下载

时间:2016-05-18 11:18:06

标签: python django

我正在尝试通过此函数提供.json文件。问题是,每次我发出请求时,浏览器都会显示内容而不是下载文件。

我认为这可能是因为我使用.read()作为HttpResponse对象构造函数的参数。但是,如果我只使用文件对象,则会出现以下异常:

TypeError: cannot serialize '_io.BufferedRandom' object

代码

try:
    invoices = models.Invoice.objects.filter(pk__in=document_ids).order_by(*ordering)
    pcustomers = models.CustomerProxy.objects.all()
    mixed_query = list(invoices) + list(pcustomers)

    file = tempfile.NamedTemporaryFile(suffix='.json')
    file.write(serializers.serialize('json', mixed_query).encode())
    file.seek(0)

    response = HttpResponse(file.read(), content_type='application/json')
    response['Content-Disposition'] = 'attachment; filename=%s' % file.name
    response['Content-Length'] = os.path.getsize(file.name)

except Exception:
    raise

return response

3 个答案:

答案 0 :(得分:3)

您无需完成整个文件生成过程即可创建可下载文件,只需正常添加Content-Disposition标头即可。下面的代码是否有效?

...
mixed_query = list(invoices) + list(pcustomers)
json_str = serializers.serialize('json', mixed_query))
response = HttpResponse(json_str, content_type='application/json')
response['Content-Disposition'] = 'attachment; filename=export.json'

答案 1 :(得分:1)

将此添加到您的Http响应中

HttpResponse(mimetype='application/force-download')

答案 2 :(得分:1)

根据您显示的代码,您无需写入临时文件。为什么不将serialize()的结果传递给HttpResponse()

response = HttpResponse(serializers.serialize('json', mixed_query), content_type='application/json')

您可以将附件名称设置为您喜欢的任何内容,描述性内容似乎比tempfile.NamedTemporaryFile()生成的随机字母数字字符串更好。

response['Content-Disposition'] = 'attachment; filename="invoices_and_customers.json"'

如果你真的想指定长度:

response['Content-Length'] = len(response.content)

或者您可以将ConditionalGetMiddleware中间件添加到您的设置中,让Django为您添加Content-Length