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>