Django 提供三种方式实现文件下载功能,分别是:HttpResponse、StreamingHttpResponse和FileResponse,三者的说明如下:
- HttpResponse 是所有响应过程的核心类,它的底层功能类是HttpResponseBase。
- StreamingHttpResponse 是在HttpResponseBase 的基础上进行继承与重写的,它实现流式响应输出(流式响应输出是使用Python的迭代器将数据进行分段处理并传输的),适用于大规模数据响应和文件传输响应。
- FileResponse 是在StreamingHttpResponse 的基础上进行继承与重写的,它实现文件的流式响应输出,只适用于文件传输响应。
HttpResponse、StreamingHttpResponse和FileResponse 这三者的差异:
- HttpResponse 实现文件下载存在很大弊端,其工作原理是将文件读取并载入内存,然后输出到浏览器上实现下载功能。如果文件较大,该方法就会占用很多内存。对于下载大文件,Django推荐使用StreamingHttpResponse 和FileResponse 方法,这两个方法将下载文件分批写入服务器的本地磁盘,减少对内存的消耗。
- StreamingHttpResponse 和FileResponse 的实现原理是相同的,两者都是将下载文件分批写入本地磁盘,实现文件的流式响应输出。
- 从适用范围来说,StreamingHttpResponse 的适用范围更为广泛,可支持大规模数据或文件输出,而FileResponse 只支持文件输出。
- 从使用方式来说,由于StreamingHttpResponse 支持数据或文件输出,因此在使用时需要设置响应输出类型和方式,而FileResponse只需设置3个参数即可实现文件下载功能。
在myApp的urls.py中路由配置:
#myApp urls.py
from argparse import Namespace
from operator import index
from django.urls import path,re_path,include
from . import views
from django.views.generic import RedirectView
urlpatterns = [
path("",views.index,name="index"),
path("download/file1",views.download1,name="download1"),
path("download/file2",views.download2,name="download2"),
path("download/file3",views.download3,name="download3"),
]
#配置全局404页面
handler404 = "myApp.views.page_not_found"
#配置全局500页面
handler500 = "myApp.views.page_error"
在myApp应用下views.py可以通过:HttpResponse、StreamingHttpResponse和FileResponse实现下载功能:
from django.shortcuts import render
from django.shortcuts import reverse
from django.urls import resolve
#文件下载包
from django.http import HttpResponse,Http404
from django.http import StreamingHttpResponse
from django.http import FileResponse
# Create your views here.
def index(request):
# return redirect("index:shop",permanent=True)
return render(request,"index.html")
def download1(request):
#服务器上存放文件的路径
file_path = r"E:\myDjango\file\1.jpg"
try:
r = HttpResponse(open(file_path,"rb"))
print(r)
r["content_type"]="application/octet-stream"
r["Content-Disposition"]="attachment;filename=1.jpg"
return r
except Exception:
raise Http404("Download error")
def download2(request):
file_path = r"E:\myDjango\file\2.jpg"
try:
r = StreamingHttpResponse(open(file_path,"rb"))
r["content_type"]="application/octet-stream"
r["Content-Disposition"]="attachment;filename=2.jpg"
return r
except Exception:
raise Http404("Download error")
def download3(request):
file_path = r"E:\myDjango\file\3.jpg"
try:
f = open(file_path,"rb")
r = FileResponse(f,as_attachment=True,filename="3.jpg")
return r
except Exception:
raise Http404("Download error")
StreamingHttpResponse 函数说明:
StreamingHttpResponse初始化参数streaming_content 和形参*args 、**kwargs。参数streaming_content的数据格式可设为迭代器对象或字节流,代表数据或文件内容。*args、**kwargs设置HttpResponseBase的参数,即响应内容的数据格式content_type 和响应状态码status等参数。
FileResponse 函数说明:
FileResponse初始化参数as_attachment 和filename。
- 参数as_attachment 的数据类型为布尔型,若为:False,则不提供文件下载功能,文件将会在浏览器里打开并读取,若浏览器无法打开文件,则将文件下载到本地计算机,但没有设置文件名后缀;若为True,则开启文件下载功能,将文件下载到本地计算机,并设置文件后缀名。
- 参数filename设置下载文件的文件名,该参数于参数as_attachment 的设置有关。若参数as_attachment为False,则参数filename不起作用,在as_attachment 为True的前提下,如果filename为空,则使用该文件原有的文件名作为下载文件的文件名,反之以参数filename作为下载文件的文件名。
- 形参*agrs、**kwargs 用于设置HttpResponseBase 的参数,即响应内容的数据格式content_type和响应状态码status等参数。
在模板中的页面下载代码:
<html>
<header>
<title>首页文件下载</title>
</header>
<body>
<a href="{%url 'myApp:download1' %}">下载1</a>
<a href="{%url 'myApp:download2' %}">下载2</a>
<a href="{%url 'myApp:download3' %}">下载3</a>
</body>
</html>