django 实现文件下载功能
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>