在 Django 中提供大文件(高负载)

新手上路,请多包涵

我一直在使用一种提供下载服务的方法,但由于它不安全,我决定改变它。 (方法是链接到存储中的原始文件,但风险是每个知道链接的人都可以下载文件!)所以我现在通过我的视图提供文件,这样只有获得许可的用户才能下载文件,但我注意到服务器负载很高,同时有许多文件同时下载请求。这是我处理用户下载的部分代码(考虑文件是图像)

     image = Image.open ("the path to file")
    response = HttpResponse(mimetype = 'image/png' )
    response['Content-Disposition'] = 'attachment: filename=%s.png' % filename
    image.save(response , "png")
    return response

在保持安全性和降低服务器端负载的同时提供文件服务有没有更好的方法?提前致谢 :)

原文由 user633784 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 479
2 个回答

您打开图像会将其加载到内存中,这就是导致大量使用时负载增加的原因。正如 Martin 所发布的那样,真正的解决方案是直接提供文件。

这是另一种方法,它将以块的形式流式传输文件而不将其加载到内存中。

 import os
import mimetypes

from wsgiref.util import FileWrapper

from django.http import StreamingHttpResponse

def download_file(request):
    the_file = "/some/file/name.png"
    filename = os.path.basename(the_file)
    chunk_size = 8192
    response = StreamingHttpResponse(
        FileWrapper(
            open(the_file, "rb"),
            chunk_size,
        ),
        content_type=mimetypes.guess_type(the_file)[0],
    )
    response["Content-Length"] = os.path.getsize(the_file)
    response["Content-Disposition"] = f"attachment; filename={filename}"
    return response

原文由 Burhan Khalid 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以使用此 答案 中所述的“发送文件”方法。

实际上你需要这个(c&p):

 response = HttpResponse(mimetype='application/force-download')
response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(file_name)
response['X-Sendfile'] = smart_str(path_to_file)
# It's usually a good idea to set the 'Content-Length' header too.
# You can also set any other required headers: Cache-Control, etc.
return response

这需要 mod_xsendfilenginxlighty 也支持)

原文由 Martin Thurau 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题