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>

 

posted @ 2022-04-10 09:10  西夏一品唐  阅读(2548)  评论(0编辑  收藏  举报