Django文件下载方法总结

方法一: 使用HttpResponse

import os
from django.http import HttpResponse
 
 
def media_file_download(request, file_path):
    with open(file_path, 'rb') as f:
        response = HttpResponse(f)
        response['content_type'] = "application/octet-stream"
        response['Content-Disposition'] = 'attachment; filename={0}'.format('test.png')
        return response

    # response也是一个类似文件的对象,有write等方法 
    with open(file_path, 'rb') as f:
        response = HttpResponse()
        response.write(f.read()) 
        response['content_type'] = "application/octet-stream"
        response['Content-Disposition'] = 'attachment; filename={0}'.format('test.png')
        return response

缺点:其工作原理是先读取文件,载入内存,然后再输出。如果下载文件很大,该方法会占用很多内存。对于下载大文件,Django更推荐StreamingHttpResponse和FileResponse方法。

方法二: 使用SteamingHttpResponse

注意:Django is designed for short-lived requests. Streaming responses will tie a worker process for the entire duration of the response. This may result in poor performance.

Django是为短期请求而设计的。流式响应将在整个响应期间绑定工作进程。这可能导致性能不佳。

import os
from django.http import StreamingHttpResponse
 

def _file_iterator(file_obj, chunk_size=512):
    file_obj.seek(0)
    while True:
        con = file_obj.read(chunk_size)
        if con:
            yield con
        else:
            break

 
def media_file_download(request, file_path):
    with open(file_path, 'rb') as f:
        response = StreamingHttpResponse(f)
        response['content_type'] = "application/octet-stream"
        response['Content-Disposition'] = 'attachment; filename={0}'.format('test.png')
        return response

    # StreamingHttpResponse还可以接受iterator作为参数
    bio = BytesIO()
    bio.writer(b'something')
    response = StreamingHttpResponse(_file_iterator(bio))
    response['content_type'] = "application/octet-stream"
    response['Content-Disposition'] = 'attachment; filename={0}'.format('test.png')
    return response

    
    

方法三: 使用FileResponse

FileResponse是StreamingHttpResponse的子类,并且针对二进制文件做了优化。更推荐用这种方法来下载文件。

接受一个以‘rb’方法打开的文件,并且会自动关闭文件,所以无需使用with上下文管理器打开,或者io.BytesIO()也可以。

import os
from django.http import FileResponse
from werkzeug.wsgi import FileWrapper
 
 
def media_file_download(request, file_path):
    response = FileResponse(open(file_path, 'rb')) #不需要设置=content_type,FileResponse会自动添加
    return response

    # 可以接收io.BytesIO对象
    buffer = io.BytesIO()

    workbook = xlwt.Workbook(encoding='utf-8')
    worksheet_1 = workbook.add_sheet('sheet1')
    worksheet_1.write(0, 0, label='id')
    workbook.save(buffer)
    buffer.seek(0)
    response = FileResponse(buffer)
    
    #如果生产环境部署在uwsgi下,可能报错,尝试用FileWrapper将文件流转为可迭代对象
    response = FileResponse(FileWrapper(buffer), as_attachment=True)
    return response

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值