django 實現文件下載功能


一、概述

在實際的項目中很多時候需要用到下載功能,如導excel、pdf或者文件下載,當然你可以使用web服務自己搭建可以用於下載的資源服務器,如nginx,這里我們主要介紹django中的文件下載。

前端實現方式

a標簽+響應頭信息

<a href="/download/1/">下載圖片</a>

 

注意:這里的1指的是MySQL表的主鍵id

 

后端實現方式

使用django有三種文件下載方式,分別是HttpResponse,StreamingHttpResponse,FileResponse

詳情,請參考鏈接

https://www.jb51.net/article/137790.htm

 

本文主要介紹StreamingHttpResponse實現方式

 

二、實際操作

新建項目

新建一個Django項目untitled1,這里的是Django 2.x版本。

目錄結構如下:

./
├── app
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── manage.py
├── templates
│   └── index.html
├── untitled1
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── upload
    └── images
        └── animation.jpg

 

默認創建了一個應用,名叫app

upload是用來存放上傳的圖片

 

簡單示例

這里以一個簡單的頁面,來介紹如何實現下載功能!

 

修改urls.py,增加路由。

注意:紅色部分,是需要修改的

from django.contrib import admin
from django.urls import path,re_path
from app import views

urlpatterns = [
    path('admin/', admin.site.urls),
 path('', views.index),
    re_path('download/(?P<id>\d+)', views.file_down,name = "download"),
]

 

修改views.py,增加視圖函數

from django.shortcuts import render, HttpResponse
from django.http import StreamingHttpResponse
import os

def index(request):
    return render(request,"index.html")

# Create your views here.
def file_down(request, id):
    """
    下載壓縮文件
    :param request:
    :param id: 數據庫id
    :return:
    """
    data = [{"id":"1","image":"animation.jpg"}]  # 模擬mysql表數據
    file_name = ""  # 文件名
    for i in data:
        if i["id"] == id:  # 判斷id一致時
            file_name = i["image"]  # 覆蓋變量
    
    base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 項目根目錄
    file_path = os.path.join(base_dir, 'upload','images', file_name)  # 下載文件的絕對路徑

    if not os.path.isfile(file_path):  # 判斷下載文件是否存在
        return HttpResponse("Sorry but Not Found the File")

    def file_iterator(file_path, chunk_size=512):
        """
        文件生成器,防止文件過大,導致內存溢出
        :param file_path: 文件絕對路徑
        :param chunk_size: 塊大小
        :return: 生成器
        """
        with open(file_path, mode='rb') as f:
            while True:
                c = f.read(chunk_size)
                if c:
                    yield c
                else:
                    break

    try:
        # 設置響應頭
        # StreamingHttpResponse將文件內容進行流式傳輸,數據量大可以用這個方法
        response = StreamingHttpResponse(file_iterator(file_path))
        # 以流的形式下載文件,這樣可以實現任意格式的文件下載
        response['Content-Type'] = 'application/octet-stream'
        # Content-Disposition就是當用戶想把請求所得的內容存為一個文件的時候提供一個默認的文件名
        response['Content-Disposition'] = 'attachment;filename="{}"'.format(file_name)
    except:
        return HttpResponse("Sorry but Not Found the File")

    return response
View Code

 

代碼解釋:

index是默認的首頁展示

file_down 是用來做下載的。

為了簡單實現,在file_down 中的data,表示數據庫中的記錄。需要指定id才能對應的文件!

其他代碼,有詳細的注釋,這里就不多介紹了

 

修改index.html,注意:這里需要指定id。這里僅做示例,固定了id。

實際情況應該查詢數據庫,使用Django模板引擎來渲染的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="/download/1/">下載圖片</a>
</body>
</html>

 

upload目錄是用來存放上傳文件的。在images里面我放了一張動漫圖片!

 

啟動項目,訪問首頁:

這里使用的是edge瀏覽器

 

點擊下載圖片,瀏覽器底部會有提示

點擊打開

 

就會打開圖片,效果如下:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM