Django文件下载的几种方式
目录
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