目录
Django文件下载
方式一:HttpResponse
这种方式简单粗暴,适合小文件的下载,但如果这个文件非常大,这种方式会占用大量的内存,甚至导致服务器崩溃。
其原理是,HttpResponse会先读取文件到内存,然后再输出。
def file_download(request):
with open(\'file_name.txt\') as f:
c = f.read()
return HttpResponse(c)
方式二: StreamingHttpResponse + 迭代器 yield
支持各种文件下载,通过文件流传输到浏览器,直接下载到硬盘。
Django,推荐使用 StreamingHttpResponse对象取代HttpResponse对象,StreamingHttpResponse对象用于将文件流发送给浏览器,与HttpResponse对象非常相似,对于文件下载功能,使用StreamingHttpResponse对象更合理。
from django.http StreamingHttpResonse
def file_download(request):
file_path = request.GET.get(\'file_path\')
file_name = request.GET.get(\'file_name\')
response = StreamingHttpResponse(file_iter(file_path+file_name)) # 获取文件流
response[\'Content-Type\'] = \'application/octet-stream\' # 支持所有流文件(二进制)
response[\'Content-Dispositon\'] = \'attachment;filename="{}"\'.format(file_name) # 下载文件名
# 文件流读取 -- 迭代器
def file_iter(file, chunk_size=1024):
# chunk_size=1024 表示一次最大1024k
with open(file, \'rb\') as f:
while True:
c = f.read(chunk_size)
if c:
yield c
else:
break
前端:
<button type=\'button\' onclick="download(\'{{ file_path }}\', \'{{ file_name }}\')"> 点击下载 </button>
<script>
function download(path, name){
location.href = "/file_download/?file_path=" + path + "&file_name=" + name // url路径
}
</script>
方式三:StreamingHttpResponse + FileWrapper
不用自己手写迭代器
from django.http StreamingHttpResonse
from wsgiref.util import FileWrapper
def file_download(request):
file_path = request.GET.get(\'file_path\')
file_name = request.GET.get(\'file_name\')
wrapper = FileWrapper(open(file_path, \'rb\')) # 将文件对象转换为可迭代对象
response = StreamingHttpResponse(wrapper) # 获取文件流
response[\'Content-Type\'] = \'application/octet-stream\' # 支持所有文件
response[\'Content-Dispositon\'] = \'attachment;filename="{}"\'.format(file_name) # 下载文件名
方式四: FileResponse
FileResponse是StreamingHttpResonse的一个子类,属于文件返回方式。
from django.http import HttpResponse, FileResponse
def file_response_download1(request, file_path, file_name):
response = FileResponse(open(file_path+file_name, \'rb\'))
response[\'content_type\'] = "application/octet-stream"
response[\'Content-Disposition\'] = \'attachment; filename=\' + file_name
return response