創(chuàng)新互聯(lián)www.cdcxhl.cn八線(xiàn)動(dòng)態(tài)BGP香港云服務(wù)器提供商,新人活動(dòng)買(mǎi)多久送多久,劃算不套路!
創(chuàng)新互聯(lián)建站專(zhuān)注于新華網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供新華營(yíng)銷(xiāo)型網(wǎng)站建設(shè),新華網(wǎng)站制作、新華網(wǎng)頁(yè)設(shè)計(jì)、新華網(wǎng)站官網(wǎng)定制、微信小程序開(kāi)發(fā)服務(wù),打造新華網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供新華網(wǎng)站排名全網(wǎng)營(yíng)銷(xiāo)落地服務(wù)。這篇文章主要介紹django從服務(wù)端下載文件到本地的方法有哪些,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
在實(shí)際的項(xiàng)目中很多時(shí)候需要用到下載功能,如導(dǎo)excel、pdf或者文件下載,當(dāng)然你可以使用web服務(wù)自己搭建可以用于下載的資源服務(wù)器,如nginx,這里我們主要介紹django中的文件下載。
這里我們將下載的文件存放在項(xiàng)目media目錄下,當(dāng)然在實(shí)際中并不會(huì)這樣做。
方式一:使用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有個(gè)很大的弊端,其工作原理是先讀取文件,載入內(nèi)存,然后再輸出。如果下載文件很大,該方法會(huì)占用很多內(nèi)存。對(duì)于下載大文件,Django更推薦StreamingHttpResponse和FileResponse方法,這兩個(gè)方法將下載文件分批(Chunks)寫(xiě)入用戶(hù)本地磁盤(pán),先不將它們載入服務(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
文件名中文亂碼問(wèn)題
其中用英文的文件名,瀏覽器顯示正常,但是用了中文后,就是默認(rèn)的文件名,如下載.xls,或者如果我用了utf-8編碼,是亂碼。解決方法如下:
response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(name))
文件私有化的兩種方法
如果你想實(shí)現(xiàn)只有登錄過(guò)的用戶(hù)才能查看和下載某些文件,大概有兩種方法,這里僅提供思路。
上傳文件放在media文件夾,文件名使用很長(zhǎng)的隨機(jī)字符串命名(uuid), 讓用戶(hù)無(wú)法根據(jù)文件名猜出這是什么文件。視圖和模板里驗(yàn)證用戶(hù)是否已登錄,登錄或通過(guò)權(quán)限驗(yàn)證后才顯示具體的url。- 簡(jiǎn)單易實(shí)現(xiàn),安全性不高,但對(duì)于一般項(xiàng)目已足夠。
上傳文件放在非media文件夾,用戶(hù)即使知道了具體文件地址也無(wú)法訪(fǎng)問(wèn),因?yàn)镈jango只會(huì)給media文件夾里每個(gè)文件創(chuàng)建獨(dú)立url資源。視圖和模板里驗(yàn)證用戶(hù)是否已登錄,登錄或通過(guò)權(quán)限驗(yàn)證后通過(guò)自己編寫(xiě)的下載方法下載文件。- 安全性高,但實(shí)現(xiàn)相對(duì)復(fù)雜。
個(gè)人下載文檔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): """ 前端傳來(lái)下載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('文檔路徑出錯(cuò)') 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,會(huì)直接打開(kāi) # attachment 瀏覽器會(huì)開(kāi)始下載 res["Content-Disposition"] = "attachment; filename*=UTF-8''{}".format(doc_filename) return res else: raise Http404("文檔不存在!")
以上是django從服務(wù)端下載文件到本地的方法有哪些的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道!