您好,登錄后才能下訂單哦!
這篇文章主要介紹django從服務端下載文件到本地的方法有哪些,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
在實際的項目中很多時候需要用到下載功能,如導excel、pdf或者文件下載,當然你可以使用web服務自己搭建可以用于下載的資源服務器,如nginx,這里我們主要介紹django中的文件下載。
這里我們將下載的文件存放在項目media目錄下,當然在實際中并不會這樣做。
方式一:使用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有個很大的弊端,其工作原理是先讀取文件,載入內存,然后再輸出。如果下載文件很大,該方法會占用很多內存。對于下載大文件,Django更推薦StreamingHttpResponse和FileResponse方法,這兩個方法將下載文件分批(Chunks)寫入用戶本地磁盤,先不將它們載入服務器內存。
方式二:使用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
文件名中文亂碼問題
其中用英文的文件名,瀏覽器顯示正常,但是用了中文后,就是默認的文件名,如下載.xls,或者如果我用了utf-8編碼,是亂碼。解決方法如下:
response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(name))
文件私有化的兩種方法
如果你想實現只有登錄過的用戶才能查看和下載某些文件,大概有兩種方法,這里僅提供思路。
上傳文件放在media文件夾,文件名使用很長的隨機字符串命名(uuid), 讓用戶無法根據文件名猜出這是什么文件。視圖和模板里驗證用戶是否已登錄,登錄或通過權限驗證后才顯示具體的url。- 簡單易實現,安全性不高,但對于一般項目已足夠。
上傳文件放在非media文件夾,用戶即使知道了具體文件地址也無法訪問,因為Django只會給media文件夾里每個文件創建獨立url資源。視圖和模板里驗證用戶是否已登錄,登錄或通過權限驗證后通過自己編寫的下載方法下載文件。- 安全性高,但實現相對復雜。
個人下載文檔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 中的規范 # 設置為inline,會直接打開 # attachment 瀏覽器會開始下載 res["Content-Disposition"] = "attachment; filename*=UTF-8''{}".format(doc_filename) return res else: raise Http404("文檔不存在!")
以上是django從服務端下載文件到本地的方法有哪些的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。