Django提供文件下载服务

13

我正在尝试提供一个包含某些内容的txt文件,但遇到了一些问题。我使用NamedTemporaryFile创建了临时文件并写入了内容,并将delete设置为false以进行调试,但是下载的文件中没有任何内容。

我猜测是响应值没有指向正确的文件,因此没有任何内容被下载。这是我的代码:

    f = NamedTemporaryFile()
    f.write(p.body)

    response = HttpResponse(FileWrapper(f), mimetype='application/force-download')
    response['Content-Disposition'] = 'attachment; filename=test-%s.txt' % p.uuid
    response['X-Sendfile'] = f.name

在进行任何其他操作之前,不要忘记刷新文件:f.flush。 - dsign
有关使用Django提供文件的更多详细信息,请参见:https://dev59.com/p3M_5IYBdhLWcg3w8ILR - Amir Ali Akbari
4个回答

21

你有考虑过这样直接通过 response 发送 p.body 吗:

response = HttpResponse(mimetype='text/plain')
response['Content-Disposition'] = 'attachment; filename="%s.txt"' % p.uuid
response.write(p.body)

1
在Django 1.9中,应该是response = HttpResponse(p.body, content_type='text/plain'); response['Content-Disposition'] = 'attachment; filename="%s.txt"' % p.uuid - Makers_F
这是正确的答案,因为它是提供文本内容的。很多想要提供二进制文件的人也会来到这里。@Saurabh Chandra Patel的回答适用于提供二进制文件。 - Mohammed Shareef C

3

XSend 需要在 response['X-Sendfile'] 中指定文件路径,因此你可以这样做:

response['X-Sendfile'] = smart_str(path_to_file)

在这里,“path_to_file”是文件的完整路径(不仅仅是文件名)。 请查看此django-snippet

1
我已经修改了代码:“response['X-Sendfile'] = smart_str(f.name)”,但仍然没有反应,我需要使用除f.name之外的其他东西吗? - Callum
它需要完整路径,而不仅仅是 f.name - 除非您将绝对路径存储在 f.name 中? - karthikr
NamedTemporaryFile 创建绝对路径。 - Michal Čihař

1
import urllib2;   
url ="http://chart.apis.google.com/chart?cht=qr&chs=300x300&chl=s&chld=H|0"; 
opener = urllib2.urlopen(url);  
mimetype = "application/octet-stream"
response = HttpResponse(opener.read(), mimetype=mimetype)
response["Content-Disposition"]= "attachment; filename=aktel.png"
return response 

1

您的方法可能会遇到几个问题:

  • 文件内容不需要刷新,按照上面的评论添加f.flush()
  • NamedTemporaryFile在关闭时被删除,当您退出函数时可能会发生这种情况,因此Web服务器没有机会使用它
  • 临时文件名可能超出了Web服务器配置为使用X-Sendfile发送的路径

也许最好使用StreamingHttpResponse而不是创建临时文件和X-Sendfile...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接