django從服務(wù)端下載文件到本地的方法有哪些

這篇文章主要介紹django從服務(wù)端下載文件到本地的方法有哪些,文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!

專注于為中小企業(yè)提供網(wǎng)站建設(shè)、成都網(wǎng)站制作服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)濱海新區(qū)免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了近千家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

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

這里我們將下載的文件存放在項目media目錄下,當(dāng)然在實際中并不會這樣做。

方式一:使用HttpResponse

import os
from django.http import HttpResponse, Http404
def media_file_download(request, file_path):
   with open(file_path, 'rb') as f:
       try:
           response = HttpResponse(f)
           response['content_type'] = "application/octet-stream"
           response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(file_path)
           return response
       except Exception:
           raise Http404

HttpResponse有個很大的弊端,其工作原理是先讀取文件,載入內(nèi)存,然后再輸出。如果下載文件很大,該方法會占用很多內(nèi)存。對于下載大文件,Django更推薦StreamingHttpResponse和FileResponse方法,這兩個方法將下載文件分批(Chunks)寫入用戶本地磁盤,先不將它們載入服務(wù)器內(nèi)存。

方式二:使用StreamingHttpResponse

import os
from django.http import HttpResponse, Http404, StreamingHttpResponse
def stream_http_download(request, file_path):
   try:
       response = StreamingHttpResponse(open(file_path, 'rb'))
       response['content_type'] = "application/octet-stream"
       response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(file_path)
       return response
   except Exception:
       raise Http404

方式三:使用FileResponse

import os
from django.http import HttpResponse, Http404, FileResponse
def file_response_download1(request, file_path):
   try:
       response = FileResponse(open(file_path, 'rb'))
       response['content_type'] = "application/octet-stream"
       response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(file_path)
       return response
   except Exception:
       raise Http404

文件名中文亂碼問題

其中用英文的文件名,瀏覽器顯示正常,但是用了中文后,就是默認(rèn)的文件名,如下載.xls,或者如果我用了utf-8編碼,是亂碼。解決方法如下:

response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(name))

文件私有化的兩種方法

如果你想實現(xiàn)只有登錄過的用戶才能查看和下載某些文件,大概有兩種方法,這里僅提供思路。

上傳文件放在media文件夾,文件名使用很長的隨機(jī)字符串命名(uuid), 讓用戶無法根據(jù)文件名猜出這是什么文件。視圖和模板里驗證用戶是否已登錄,登錄或通過權(quán)限驗證后才顯示具體的url。- 簡單易實現(xiàn),安全性不高,但對于一般項目已足夠。

上傳文件放在非media文件夾,用戶即使知道了具體文件地址也無法訪問,因為Django只會給media文件夾里每個文件創(chuàng)建獨(dú)立url資源。視圖和模板里驗證用戶是否已登錄,登錄或通過權(quán)限驗證后通過自己編寫的下載方法下載文件。- 安全性高,但實現(xiàn)相對復(fù)雜。

個人下載文檔view視圖代碼

from django.views import View
from django.conf import settings
from django.http import FileResponse,Http404
from django.utils.encoding import escape_uri_path
from .models import Doc
import requests
import logging
logger = logging.getLogger('django')
class Download(View):
    """
    前端傳來下載doc的id,后端傳給它下載地址
    """
    def get(self,request,doc_id):
        doc = Doc.objects.only('file_url').filter(is_delete=False,id = doc_id).first()
        if doc:
            doc_url = doc.file_url
            doc_url = settings.ITEM_DOMAIN_PORT + doc_url
            try:
                res = FileResponse(requests.get(doc_url,stream = True))
            except Exception as e:
                logger.info('文件獲取異常:{}'.format(e))
                raise Http404('文件獲取異常')
            file_end = doc_url.split('.')[-1]
            if not file_end:
                raise Http404('文檔路徑出錯')
            else:
                file_end = file_end.lower()
            if file_end == "pdf":
                res["Content-type"] = "application/pdf"
            elif file_end == "zip":
                res["Content-type"] = "application/zip"
            elif file_end == "doc":
                res["Content-type"] = "application/msword"
            elif file_end == "xls":
                res["Content-type"] = "application/vnd.ms-excel"
            elif file_end == "docx":
                res["Content-type"] = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
            elif file_end == "ppt":
                res["Content-type"] = "application/vnd.ms-powerpoint"
            elif file_end == "pptx":
                res["Content-type"] = "application/vnd.openxmlformats-officedocument.presentationml.
                presentation"
            else:
                raise Http404("文檔格式不正確!")
            doc_filename = escape_uri_path(doc_url.split('/')[-1])
            # http1.1 中的規(guī)范
            # 設(shè)置為inline,會直接打開
            # attachment 瀏覽器會開始下載
            res["Content-Disposition"] = "attachment; filename*=UTF-8''{}".format(doc_filename)
            return res
        else:
            raise Http404("文檔不存在!")

以上是django從服務(wù)端下載文件到本地的方法有哪些的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

網(wǎng)站名稱:django從服務(wù)端下載文件到本地的方法有哪些
地址分享:http://muchs.cn/article0/johsoo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作外貿(mào)建站、虛擬主機(jī)搜索引擎優(yōu)化、商城網(wǎng)站響應(yīng)式網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計