1. 程式人生 > 其它 >django 實現檔案下載功能

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>