【技術博客】Django中文件下載的實現

開發組在開發過程當中,都不可避免地遇到了一些困難或問題,但都最終想出辦法克服了。咱們認爲這樣的經驗是有必要記錄下來的,所以就有了【技術博客】。html


Django中文件下載的實現

一、背景

在VisualPytorch項目中,當時須要提供一個文件下載的功能。最初想到的方案主要有一下三種前端

  • 直接把網頁前端的字符串寫入文件中,在客戶端完成。

這個方案通過查找資料發現不一樣瀏覽器的同源策略以及安全策略不盡相同,難以實現,放棄。python

  • 在服務器上再開一個ftp服務器系統地提供文件服務。

這是最開始的思路,後來根據實際需求認爲目前服務器性能自己就有限,加上目前項目對文件需求比較簡單,不須要複雜的文件服務。django

  • 直接在服務器固定目錄下生成文件,打包後經過http流的形式傳輸

最終採用的實現方法,比較簡單好實現。後端

二、Django後端中的文件打包與下載

關於文件打包,在實現時使用了zipfile這個python包瀏覽器

zipf = zipfile.ZipFile("project_VisualPytorch.zip", 'w',zipfile.ZIP_DEFLATED)

關於zipfile的使用詳情請見https://docs.python.org/3/library/zipfile.html緩存

服務器後臺是經過構造Http的response對象向前端發送數據的,對於較大的文件傳輸來講,這裏推薦使用Django框架中的StreamingHttpResponse或FileResponse構造響應對象。安全

StreamingHttpResponse採用流式傳輸文件,參數是一個迭代器,對文件進行分片傳輸,實現以下服務器

response = StreamingHttpResponse(file_iterator("project_VisualPytorch.zip"))
response['Content-Type'] = 'application/zip'
response['Content-Disposition'] = 'attachment;filename="project_VisualPytorch.zip"'
return response

迭代器構造以下app

def file_iterator(file_name, chunk_size=512):
    with open(file_name, 'rb') as f:
        while True:
            c = f.read(chunk_size)
            if c:
                yield c
            else:
                break

這裏設置分片大小爲512。

FileResponse是StreamingHttpResponse的子類,使用了緩存等技術,某些狀況下優於其父類。

相關文章
相關標籤/搜索