带mod_XSENDFILE的Django无法下载完整文件

时间:2011-09-12 06:40:35

标签: django file download

附件是使用django 1.3和带有mod_xsendfile的Apache 2.2从浏览器下载文件的代码

@login_required
def sendfile(request, productid):       
    path = settings.RESOURCES_DIR
    filepath = os.path.join('C:/workspace/y/src/y/media/audio/','sleep_away.mp3')  
    print "filepath",filepath  
    filename = 'sleep_away.mp3' # Select your file here.   
    print "Within sendfile size", os.path.getsize(filepath)
    wrapper = FileWrapper(open(filepath,'r'))     
    content_type = mimetypes.guess_type(filename)[0]     
    response = HttpResponse(wrapper, content_type = content_type) 
    print "Within wrapper"
    from django.utils.encoding import smart_str
    response['X-Sendfile'] = smart_str(filepath)
    response['Content-Length'] = os.path.getsize(filepath) 
    from django.utils.encoding import  smart_str    
    response['Content-Disposition'] = 'attachment; filename=%s/' % smart_str(filename)      
    return response 

控制台显示以下大小合适的文件大小 在sendfile大小4842585

但是当我下载/保存文件时,显示107 KB ...即109,787字节。我哪里出错了。为什么不下载完整的文件?

2 个答案:

答案 0 :(得分:2)

我认为你是django或python的新手。尝试将import语句放在method的开头。导入后,可以通过该方法使用,每次使用时都不需要导入。在Windows中,您应该使用"rb"(读取二进制文件)来提供除文本文件之外的任何内容。尽量不要使用可能与方法名称或该语言的其他关键字冲突的变量名称。你的方法应该是这样的

@login_required
def sendfile(request, productid):
    from django.utils.encoding import smart_str

    ##set path and filename
    resource_path = settings.RESOURCES_DIR # resource dir ie /workspace/y/src/y/media
    filename = "sleep_away.mp3" #file to be served 

    ##add it to os.path  
    filepath = os.path.join(resource_path,"audio",filename)
    print "complete file path: ", filepath     

    ##filewrapper to server in size of 8kb each until whole file is served   
    file_wrapper = FileWrapper(file(filepath,'rb')) ##windows needs rb (read binary) for non text files   

    ##get file mimetype
    file_mimetype = mimetypes.guess_type(filepath)

    ##create response with file_mimetype and file_wrapper      
    response = HttpResponse(content_type=file_mimetype, file_wrapper)

    ##set X-sendfile header with filepath
    response['X-Sendfile'] = filepath ##no need for smart_str here.

    ##get filesize
    print "sendfile size", os.stat(filepath).st_size
    response['Content-Length'] = os.stat(filepath).st_size ##set content length    
    response['Content-Disposition'] = 'attachment; filename=%s/' % smart_str(filename) ##set disposition     

    return response ## all done, hurray!! return response :)

希望有所帮助

答案 1 :(得分:0)

您可以查看django-private-files项目。没有自己测试过,但它看起来很有意思。 链接到文档 - > http://readthedocs.org/docs/django-private-files/en/latest/usage.html

欢呼声