Django FileResponse-如何加快文件下载

时间:2018-08-04 16:09:04

标签: django performance download

我有一个设置,可以让用户下载以BYTEA数据形式存储在数据库中的文件。一切正常,只是下载速度非常慢...似乎以33KB的块下载,每秒一块。

我可以指定一个设置来加快速度吗?

views.py

from django.http import FileResponse

def getFileResponse(filedata, filename, filesize, contenttype):
    response = FileResponse(filedata, content_type=contenttype)
    response['Content-Disposition'] = 'attachment; filename=%s' % filename
    response['Content-Length'] = filesize
    return response

return getFileResponse(
    filedata = myfile.filedata, # Binary data from DB
    filename = myfile.filename + myfile.fileextension, 
    filesize = myfile.filesize, 
    contenttype = myfile.filetype
)

以前,我将二进制数据作为HttpResponse返回,并像普通文件一样以正常速度下载。在本地可以正常使用,但是当我推送到Heroku时,它不会下载文件-而是在下载文件中显示<Memory at XXX>

另一个问题...当我包含具有非ASCII数据(即á)的文本文件时,我也会收到错误消息:

UnicodeEncodeError: 'ascii' codec can't encode characters...: ordinal not in range(128)

如何处理带有Unicode数据的文件?

更新

有人知道为什么从HTTPResponse更改为FileResponse时下载速度如此之慢?或者,为什么HTTPResponse返回文件在Heroku上不起作用?

2 个答案:

答案 0 :(得分:1)

我认为您在HttpResponse与FileResponse之间观察到的差异是由规范引起的:https://www.python.org/dev/peps/pep-3333/#buffering-and-streaming

在您之前的代码中,创建了一个HttpResponse,其中包含一个包含整个文件的大字节字符串,并且第一次迭代传递返回了完整的响应主体。使用FileResponse时,文件将以大块(4 kb,8 kb或其他大小,具体取决于您的WSGI应用服务器)进行迭代,(我认为)该块立即在上游流(先到反向代理再到客户端),这可能会增加开销(更多通信)超出过程边界?)。

了解所使用的应用服务器(uwsgi,gunicorn,女服务员等)及其相关配置会有所帮助。还有更多有关heroku错误的详细信息,以防万一!

答案 1 :(得分:0)

为什么要将整个文件存储在数据库中。

最好的情况是将文件存储在硬盘上,而仅将路径存储在数据库上

然后根据您的Web服务器,让Web服务器提供文件。

Web服务比Django更好地提供文件。

如果文件无访问权限,请选中将它们存储在介质上

如果您的文件具有访问控制权,那么您可以根据网络服务器使用一些响应标头

如果您使用Nginx,则必须使用X-Accel-Redirect并在https://wellfire.co/learn/nginx-django-x-accel-redirects/上的其他Web服务教程上使用任何替代方法