最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Django 大文件下載實(shí)現(xiàn)過程解析

 更新時間:2019年08月01日 10:07:53   作者:再見紫羅蘭  
這篇文章主要介紹了Django 大文件下載實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

django提供文件下載時,若果文件較小,解決辦法是先將要傳送的內(nèi)容全生成在內(nèi)存中,然后再一次性傳入Response對象中:

def simple_file_download(request):
  # do something...
  content = open("simplefile", "rb").read()

如果文件非常大時,最簡單的辦法就是使用靜態(tài)文件服務(wù)器,比如Apache或者Nginx服務(wù)器來處理下載。不過有時候,我們需要對用戶的權(quán)限做一下限定,或者不想向用戶暴露文件的真實(shí)地址,或者這個大內(nèi)容是臨時生成的(比如臨時將多個文件合并而成的),這時就不能使用靜態(tài)文件服務(wù)器了。

django文檔中提到,可以向HttpResponse傳遞一個迭代器,流式的向客戶端傳遞數(shù)據(jù)。

要自己寫迭代器的話,可以用yield:

def read_file(filename, buf_size=8192):
  with open(filename, "rb") as f:
    while True:
      content = f.read(buf_size)
      if content:
        yield content
      else:
        break
def big_file_download(request):
  filename = "filename"
  response = HttpResponse(read_file(filename))
  return response

或者使用生成器表達(dá)式,下面是django文檔中提供csv大文件下載的例子:

import csv
 
from django.utils.six.moves import range
from django.http import StreamingHttpResponse
 
class Echo(object):
  """An object that implements just the write method of the file-like
  interface.
  """
  def write(self, value):
    """Write the value by returning it, instead of storing in a buffer."""
    return value
 
def some_streaming_csv_view(request):
  """A view that streams a large CSV file."""
  # Generate a sequence of rows. The range is based on the maximum number of
  # rows that can be handled by a single sheet in most spreadsheet
  # applications.
  rows = (["Row {0}".format(idx), str(idx)] for idx in range(65536))
  pseudo_buffer = Echo()
  writer = csv.writer(pseudo_buffer)
  response = StreamingHttpResponse((writer.writerow(row) for row in rows),
                   content_type="text/csv")
  response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'
  return response

python也提供一個文件包裝器,將類文件對象包裝成一個迭代器:

class FileWrapper:
  """Wrapper to convert file-like objects to iterables""" 
  def __init__(self, filelike, blksize=8192):
    self.filelike = filelike
    self.blksize = blksize
    if hasattr(filelike,'close'):
      self.close = filelike.close 
  def __getitem__(self,key):
    data = self.filelike.read(self.blksize)
    if data:
      return data
    raise IndexError 
  def __iter__(self):
    return self 
  def next(self):
    data = self.filelike.read(self.blksize)
    if data:
      return data
    raise StopIteration

使用時:

from django.core.servers.basehttp import FileWrapper
from django.http import HttpResponse
import os
def file_download(request,filename):
 
  wrapper = FileWrapper(open(filename, 'rb'))
  response = HttpResponse(wrapper, content_type='application/octet-stream')
  response['Content-Length'] = os.path.getsize(path)
  response['Content-Disposition'] = 'attachment; filename=%s' % filename
  return response

django也提供了StreamingHttpResponse類來代替HttpResponse對流數(shù)據(jù)進(jìn)行處理。

壓縮為zip文件下載:

import os, tempfile, zipfile 
from django.http import HttpResponse 
from django.core.servers.basehttp import FileWrapper 
def send_zipfile(request): 
  """                                     
  Create a ZIP file on disk and transmit it in chunks of 8KB,         
  without loading the whole file into memory. A similar approach can     
  be used for large dynamic PDF files.                    
  """ 
  temp = tempfile.TemporaryFile() 
  archive = zipfile.ZipFile(temp, 'w', zipfile.ZIP_DEFLATED) 
  for index in range(10): 
    filename = __file__ # Select your files here.              
    archive.write(filename, 'file%d.txt' % index) 
  archive.close() 
  wrapper = FileWrapper(temp) 
  response = HttpResponse(wrapper, content_type='application/zip') 
  response['Content-Disposition'] = 'attachment; filename=test.zip' 
  response['Content-Length'] = temp.tell() 
  temp.seek(0) 
  return response

不過不管怎么樣,使用django來處理大文件下載都不是一個很好的注意,最好的辦法是django做權(quán)限判斷,然后讓靜態(tài)服務(wù)器處理下載。

這需要使用sendfile的機(jī)制:"傳統(tǒng)的Web服務(wù)器在處理文件下載的時候,總是先讀入文件內(nèi)容到應(yīng)用程序內(nèi)存,然后再把內(nèi)存當(dāng)中的內(nèi)容發(fā)送給客戶端瀏覽器。這種方式在應(yīng)付當(dāng)今大負(fù)載網(wǎng)站會消耗更多的服務(wù)器資源。sendfile是現(xiàn)代操作系統(tǒng)支持的一種高性能網(wǎng)絡(luò)IO方式,操作系統(tǒng)內(nèi)核的sendfile調(diào)用可以將文件內(nèi)容直接推送到網(wǎng)卡的buffer當(dāng)中,從而避免了Web服務(wù)器讀寫文件的開銷,實(shí)現(xiàn)了“零拷貝”模式。 "

Apache服務(wù)器里需要mod_xsendfile模塊來實(shí)現(xiàn),而Nginx是通過稱為X-Accel-Redirect的特性來實(shí)現(xiàn)。

nginx配置文件:

# Will serve /var/www/files/myfile.tar.gz
# When passed URI /protected_files/myfile.tar.gz
location /protected_files {
  internal;
  alias /var/www/files;
}

或者

# Will serve /var/www/protected_files/myfile.tar.gz
# When passed URI /protected_files/myfile.tar.gz
location /protected_files {
  internal;
  root /var/www;
}

注意alias和root的區(qū)別。

django中:

response['X-Accel-Redirect']='/protected_files/%s'%filename

這樣當(dāng)向django view函數(shù)發(fā)起request時,django負(fù)責(zé)對用戶權(quán)限進(jìn)行判斷或者做些其它事情,然后向nginx轉(zhuǎn)發(fā)url為/protected_files/filename的請求,nginx服務(wù)器負(fù)責(zé)文件/var/www/protected_files/filename的下載:

@login_required
def document_view(request, document_id):
  book = Book.objects.get(id=document_id)
  response = HttpResponse()
  name=book.myBook.name.split('/')[-1]
  response['Content_Type']='application/octet-stream'
  response["Content-Disposition"] = "attachment; filename={0}".format(
      name.encode('utf-8'))
  response['Content-Length'] = os.path.getsize(book.myBook.path)
  response['X-Accel-Redirect'] = "/protected/{0}".format(book.myBook.name)
  return response

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • python獲取局域網(wǎng)占帶寬最大3個ip的方法

    python獲取局域網(wǎng)占帶寬最大3個ip的方法

    這篇文章主要介紹了python獲取局域網(wǎng)占帶寬最大3個ip的方法,涉及Python解析URL參數(shù)的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • 利用Python如何實(shí)現(xiàn)數(shù)據(jù)驅(qū)動的接口自動化測試

    利用Python如何實(shí)現(xiàn)數(shù)據(jù)驅(qū)動的接口自動化測試

    這篇文章主要給大家介紹了關(guān)于利用Python如何實(shí)現(xiàn)數(shù)據(jù)驅(qū)動的接口自動化測試的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價值,需要的朋友們來一起看看吧
    2018-05-05
  • 如何判斷pytorch是否支持GPU加速

    如何判斷pytorch是否支持GPU加速

    這篇文章主要介紹了判斷pytorch是否支持GPU加速的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • python3.6?print同一行覆蓋打印方式

    python3.6?print同一行覆蓋打印方式

    這篇文章主要介紹了python3.6?print同一行覆蓋打印方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 使用python實(shí)現(xiàn)畫AR模型時序圖

    使用python實(shí)現(xiàn)畫AR模型時序圖

    今天小編就為大家分享一篇使用python實(shí)現(xiàn)畫AR模型時序圖,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • Django分頁器的用法詳解

    Django分頁器的用法詳解

    本文主要介紹在利用Django開發(fā)MVT模型項(xiàng)目時分頁器的使用,感興趣的朋友可以參考下
    2021-05-05
  • python實(shí)現(xiàn)網(wǎng)頁自動簽到功能

    python實(shí)現(xiàn)網(wǎng)頁自動簽到功能

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)網(wǎng)頁自動簽到功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • python算法與數(shù)據(jù)結(jié)構(gòu)之單鏈表的實(shí)現(xiàn)代碼

    python算法與數(shù)據(jù)結(jié)構(gòu)之單鏈表的實(shí)現(xiàn)代碼

    鏈表是一種物理存儲單元上非連續(xù)、非順序的存儲結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序?qū)崿F(xiàn)的。這篇文章主要介紹了python算法與數(shù)據(jù)結(jié)構(gòu)之單鏈表的實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2019-06-06
  • Python Django模板之模板過濾器與自定義模板過濾器示例

    Python Django模板之模板過濾器與自定義模板過濾器示例

    這篇文章主要介紹了Python Django模板之模板過濾器與自定義模板過濾器,結(jié)合實(shí)例形式分析了Django框架模板過濾器與自定義模板過濾器相關(guān)功能、原理、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-10-10
  • python二維碼操作:對QRCode和MyQR入門詳解

    python二維碼操作:對QRCode和MyQR入門詳解

    今天小編就為大家分享一篇python二維碼操作:對QRCode和MyQR入門詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-06-06

最新評論

略阳县| 翁源县| 洪湖市| 托克逊县| 泾阳县| 千阳县| 太和县| 宜阳县| 延寿县| 霍城县| 许昌市| 横山县| 德安县| 安仁县| 平泉县| 全南县| 达孜县| 泽普县| 五原县| 顺昌县| 红原县| 南投市| 长丰县| 岐山县| 大埔区| 土默特右旗| 日喀则市| 邓州市| 岳阳县| 临沭县| 额敏县| 攀枝花市| 临猗县| 阜城县| 中卫市| 敦煌市| 麻阳| 德兴市| 大同县| 萨嘎县| 玉门市|