开发者

Django with mod_XSENDFILE unable to download complete file

开发者 https://www.devze.com 2023-04-03 23:48 出处:网络
Attached is the code which downloads a file from browser using django 1.3 and Apache 2.2 with mod_xsendfile

Attached is the code which downloads a file from browser using django 1.3 and Apache 2.2 with mod_xsendfile

@login_required
def sendfile(request, productid):       
    path = settings.RESOURCES_DIR
    filepath = os.path.join('C:/workspace/y/src/y/media/开发者_Go百科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 

The console shows the following filesize which is the right size Within sendfile size 4842585

But when I download/save the file it shows 107 KB...i.e 109,787 bytes.Where am I going wrong. Why isnt it downloading the complete file?


I consider your new to django or python. Try to put the import statements at the beginning of the method. Once imported it can be used through the method no need import every time you use. In windows you should use "rb" (read binary) to serve anything other than text files. Try not to use variable names that might conflict with method names or other keywords of the language. Your method should be like this

@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 :)

Hope that helps


You could have a look at the django-private-files project. Haven't tested it myself, but it looks promissing. link to the docs --> http://readthedocs.org/docs/django-private-files/en/latest/usage.html

cheers

0

精彩评论

暂无评论...
验证码 换一张
取 消