Python Django Filewrapper内存错误服务大文件,如何流

Python Django Filewrapper内存错误服务大文件,如何流,python,django,file,download,streaming,Python,Django,File,Download,Streaming,我有这样的代码: @login_required def download_file(request): content_type = "application/octet-stream" download_name = os.path.join(DATA_ROOT, "video.avi") with open(download_name, "rb") as f: wrapper = FileWrapper(f, 8192) respo

我有这样的代码:

@login_required
def download_file(request):
    content_type = "application/octet-stream"
    download_name = os.path.join(DATA_ROOT, "video.avi")

    with open(download_name, "rb") as f:
        wrapper = FileWrapper(f, 8192)
        response = HttpResponse(wrapper, content_type=content_type)
    response['Content-Disposition'] = 'attachment; filename=blabla.avi'
    response['Content-Length'] = os.path.getsize(download_name)
    # response['Content-Length'] = _file.size
    return response
它似乎起作用了。然而,如果我下载更大的文件(例如约600MB),我的内存消耗将增加600MB。在几次这样的下载之后,我的服务器抛出:

内部服务器错误:/download/Traceback(最近一次呼叫最后一次):
文件 “/home/matous/.local/lib/python3.5/site packages/django/core/handlers/exception.py”, 第35行,在内部 response=get_response(请求)文件“/home/matous/.local/lib/python3.5/site packages/django/core/handlers/base.py”, 第128行,在“获取”响应中 response=self.process\u exception\u by\u中间件(e,请求)文件“/home/matous/.local/lib/python3.5/site packages/django/core/handlers/base.py”, 第126行,在“获取”响应中 response=wrapped_callback(请求,*callback_args,**callback_kwargs)文件“/home/matous/.local/lib/python3.5/site packages/django/contrib/auth/decorators.py”, 第21行,在视图中 返回视图_func(请求,*args,**kwargs)文件“/media/matous/89104d3d-fa52-4b14-9c5d-9ec54ceebbb/home/matous/phd/emoapp/emoapp/mainapp/views.py”, 第118行,在下载文件中 response=HttpResponse(包装器,content\u type=content\u type)文件“/home/matous/.local/lib/python3.5/site packages/django/http/response.py”, 第285行,在init self.content=content文件“/home/matous/.local/lib/python3.5/site packages/django/http/response.py”, 第308行,在内容中 content=b“”。连接(值中的块的self.make_字节(块))MemoryError

我做错了什么?有没有可能在没有这种疯狂的内存存储的情况下,以某种方式将其配置为从硬盘逐块传输


注意:我知道Django不应该为大文件提供服务,但我正在寻找一种简单的方法,允许验证用户对任何提供的文件的访问权限。

尝试使用
StreamingHttpResponse
,这将有所帮助,这正是您要寻找的

有没有可能在没有这种疯狂的内存存储的情况下,以某种方式将其配置为从硬盘逐块传输

导入操作系统
从django.http导入StreamingHttpResponse
从django.core.servers.basehttp导入文件包装器#django 1.8
@需要登录
def下载_文件(请求):
file_path=os.path.join(DATA_ROOT,“video.avi”)
filename=os.path.basename(文件路径)
块大小=8192
响应=StreamingHttpResponse(
FileWrapper(打开(文件路径,'rb'),块大小),
content\u type=“应用程序/八位字节流”
)
响应['Content-Length']=os.path.getsize(文件路径)
响应['Content-Disposition']=“附件;文件名=%s”%filename
返回响应
这将以块的形式流式传输您的文件,而无需将其加载到内存中;或者,您可以使用

这是针对二进制优化的
StreamingHttpResponse
的子类 档案


尝试使用
StreamingHttpResponse
,这样会有所帮助,这正是您要寻找的

有没有可能在没有这种疯狂的内存存储的情况下,以某种方式将其配置为从硬盘逐块传输

导入操作系统
从django.http导入StreamingHttpResponse
从django.core.servers.basehttp导入文件包装器#django 1.8
@需要登录
def下载_文件(请求):
file_path=os.path.join(DATA_ROOT,“video.avi”)
filename=os.path.basename(文件路径)
块大小=8192
响应=StreamingHttpResponse(
FileWrapper(打开(文件路径,'rb'),块大小),
content\u type=“应用程序/八位字节流”
)
响应['Content-Length']=os.path.getsize(文件路径)
响应['Content-Disposition']=“附件;文件名=%s”%filename
返回响应
这将以块的形式流式传输您的文件,而无需将其加载到内存中;或者,您可以使用

这是针对二进制优化的
StreamingHttpResponse
的子类 档案

import os
from django.http import StreamingHttpResponse
from django.core.servers.basehttp import FileWrapper #django <=1.8
from wsgiref.util import FileWrapper #django >1.8

@login_required
def download_file(request):
   file_path = os.path.join(DATA_ROOT, "video.avi")
   filename = os.path.basename(file_path)
   chunk_size = 8192
   response = StreamingHttpResponse(
       FileWrapper(open(file_path, 'rb'), chunk_size),
       content_type="application/octet-stream"
   )
   response['Content-Length'] = os.path.getsize(file_path)    
   response['Content-Disposition'] = "attachment; filename=%s" % filename
   return response