Heim  >  Artikel  >  Web-Frontend  >  So implementieren Sie die Funktion zum Herunterladen von Dateien in Django

So implementieren Sie die Funktion zum Herunterladen von Dateien in Django

php中世界最好的语言
php中世界最好的语言Original
2018-04-11 17:17:143200Durchsuche

Dieses Mal zeige ich Ihnen, wie Sie die Funktion zum Herunterladen von Dateien in Django implementieren Ein praktischer Fall. Wenn eine auf Django basierende Website eine Funktion zum Herunterladen von Dateien bietet, ist es am einfachsten, die statischen Dateien zur Verarbeitung an Nginx zu übergeben. Aufgrund der Logik der Website selbst ist dies jedoch manchmal erforderlich Bereitstellung der Download-Funktion über Django, z. B. Seitendaten-Exportfunktion (dynamisch generierte Dateien herunterladen), Überprüfung der Benutzerberechtigungen vor dem Herunterladen von Dateien usw. Daher ist es notwendig, die Implementierung der Datei-Download-Funktion in Django zu untersuchen.

Die Implementierung der einfachsten Datei-Download-Funktion

Fügen Sie einfach den Dateistream in das HttpResponse-Objekt ein, z. B.:

Diese Methode ist einfach und grob und eignet sich zum Herunterladen kleiner Dateien. Wenn die Datei jedoch sehr groß ist, belegt sie viel Speicher und führt sogar zum Absturz des Servers

def file_download(request):
  # do something...
  with open('file_name.txt') as f:
    c = f.read()
  return HttpResponse(c)
Vernünftigere Funktion zum Herunterladen von Dateien

Das HttpResponse-Objekt von Django ermöglicht die Übergabe von Iteratoren als Parameter. Durch Ersetzen des eingehenden Parameters c im obigen Code kann die obige Download-Funktion so optimiert werden, dass sie sowohl für große als auch für kleine Dateien geeignet ist Die Verwendung des StreamingHttpResponse-Objekts wird zum Senden eines Dateistreams an den Browser empfohlen. Für die Datei-Download-Funktion ist es sinnvoller, das StreamingHttpResponse-Objekt zu verwenden. Daher sollte eine vernünftigere Funktion zum Herunterladen von Dateien zunächst einen Iterator für

schreiben, um die Datei

zu verarbeiten, und diesen Iterator dann als Parameter an das StreaminghttpResponse-Objekt übergeben, z. B.:

Die Funktion zum Herunterladen von Dateien wurde erneut optimiert

from django.http import StreamingHttpResponse
def big_file_download(request):
  # do something...
 
  def file_iterator(file_name, chunk_size=512):
    with open(file_name) as f:
      while True:
        c = f.read(chunk_size)
        if c:
          yield c
        else:
          break
 
  the_file_name = "file_name.txt"
  response = StreamingHttpResponse(file_iterator(the_file_name))
 
  return response

Der obige Code hat die Übertragung der Dateien vom Server an den Browser durch Datei-Streaming abgeschlossen. Der Dateistream wird jedoch normalerweise in verstümmelter Form angezeigt, anstatt auf die Festplatte heruntergeladen zu werden. Lassen Sie den Dateistream auf die Festplatte schreiben. Die Optimierung ist sehr einfach. Weisen Sie den Feldern Content-Type und Content-Disposition des StreamingHttpResponse-Objekts einfach die folgenden Werte zu, z. B.:

Der vollständige Code lautet wie folgt:

response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="test.pdf"'

Spezifisches Exportdateiformat

from django.http import StreamingHttpResponse
def big_file_download(request):
  # do something... 
  def file_iterator(file_name, chunk_size=512):
    with open(file_name) as f:
      while True:
        c = f.read(chunk_size)
        if c:
          yield c
        else:
          break
 
  the_file_name = "big_file.pdf"
  response = StreamingHttpResponse(file_iterator(the_file_name))
  response['Content-Type'] = 'application/octet-stream'
  response['Content-Disposition'] = 'attachment;filename="{0}"'.format(the_file_name) 
  return response

Excel-Tabelle exportieren

1. Exportieren Sie zunächst die Excel-Tabelle direkt

Besorgen Sie sich zunächst die zu exportierenden Daten und speichern Sie diese in Listenform. Die Daten werden dann in Excel geschrieben und per Streaming an die Seite zum Herunterladen zurückgegeben.

2. JSON-Datei exportieren

import xlwt
import io
import json
from django.http import HttpResponse
def set_style(name, height, bold=False):
  style = xlwt.XFStyle() # 初始化样式
  font = xlwt.Font() # 为样式创建字体
  font.name = name # 'Times New Roman'
  font.bold = bold
  font.color_index = 000
  font.height = height
  style.font = font
  # 设置单元格边框
  # borders= xlwt.Borders()
  # borders.left= 6
  # borders.right= 6
  # borders.top= 6
  # borders.bottom= 6
  # style.borders = borders
  # 设置单元格背景颜色
  # pattern = xlwt.Pattern()
  # 设置其模式为实型
  # pattern.pattern = pattern.SOLID_PATTERN
  # 设置单元格背景颜色
  # pattern.pattern_fore_colour = 0x00
  # style.pattern = pattern
  return style
def write_excel(data, name, header):
  # 打开一个Excel工作簿
  file = xlwt.Workbook()
  # 新建一个sheet,如果对一个单元格重复操作,会引发异常,所以加上参数cell_overwrite_ok=True
  table = file.add_sheet(name, cell_overwrite_ok=True)
  if data is None:
    return file
  # 写标题栏
  row0 = [u'业务', u'状态', u'北京', u'上海', u'广州', u'深圳', u'状态小计']
  for i in range(0, len(row0)):
    table.write_merge(0, 0, i, i, row0[i], set_style('Times New Roman', 220, True))
  table.write_merge(0, 2, 7, 9, "单元格合并", set_style('Times New Roman', 220, True))
  """
  table.write_merge(x, x + m, y, w + n, string, sytle)
x表示行,y表示列,m表示跨行个数,n表示跨列个数,string表示要写入的单元格内容,style表示单元格样式。其中,x,y,w,h,都是以0开始计算的。
  """
  l = 0
  n = len(header)
  # 写入数据
  for line in data:
    for i in range(n):
      table.write(l, i, line[header[i]])
    l += 1
  # 直接保存文件
  # file.save("D:/excel_name.xls")
  # 写入IO
  res = get_excel_stream(file)
  # 设置HttpResponse的类型
  response = HttpResponse(content_type='application/vnd.ms-excel')
  from urllib import parse
  response['Content-Disposition'] = 'attachment;filename=' + parse.quote("excel_name") + '.xls'
  # 将文件流写入到response返回
  response.write(res)
  return response
def get_excel_stream(file):
  # StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。
  excel_stream = io.BytesIO()
  # 这点很重要,传给save函数的不是保存文件名,而是一个BytesIO流(在内存中读写)
  file.save(excel_stream)
  # getvalue方法用于获得写入后的byte将结果返回给re
  res = excel_stream.getvalue()
  excel_stream.close()
  return res

Das Exportieren von JSON-Dateien ist nicht so mühsam wie in Excel. Sie müssen nur Daten im JSON-Format zusammenfügen. Der direkte Export in eine Webseite ist jedoch möglich Die Einheimischen mögen es, Excel zu exportieren?

3. Komprimiertes Paket exportieren

def write_json(data):
  try:
    json_stream = get_json_stream(data)
    response = HttpResponse(content_type='application/json')
    from urllib import parse
    response['Content-Disposition'] = 'attachment;filename=' + parse.quote("test") + '.json'
    response.write(json_stream)
    return response
  except Exception as e:
    print(e)
def get_json_stream(data):
  # 开始这里我用ByteIO流总是出错,但是后来参考廖雪峰网站用StringIO就没问题
  file = io.StringIO()
  data = json.dumps(data)
  file.write(data)
  res = file.getvalue()
  file.close()
  return res

Da beim Exportieren zweier Dateien nicht beide gleichzeitig zurückgegeben werden können, sollten Sie erwägen, die beiden Dateien in ein Paket zu packen und das Paket dann als Stream zurückzugeben. denken? Was derzeit exportiert wird, befindet sich in einem Zip-Paket. Wie schreibe ich diese beiden Dateiströme in das Zip-Paket? Später wurden unter Anleitung des Chefs die zu packenden Dateien lokal gespeichert. Nach dem Packen in Zip wurden die lokalen Dateien gelöscht. Anschließend wurde der Zip-Dateistream gelesen, in die Antwort geschrieben und an die Zip zurückgegeben Dateistream.

Ich glaube, dass Sie die Methode beherrschen, nachdem Sie den Fall in diesem Artikel gelesen haben. Weitere spannende Informationen finden Sie in anderen verwandten Artikeln auf der chinesischen PHP-Website.

Empfohlene Lektüre:
def write_zip(e_data, j_data, export_name):
  try:
    # 保存到本地文件
    # 返回文件名,注意此时保存的方法和前面导出保存的json、excel文件区别
    j_name = write_json(j_data, export_name[1])
    e_name = write_excel(e_data, export_name[1])
    # 本地文件写入zip,重命名,然后删除本地临时文件
    z_name='export.zip'
    z_file = zipfile.ZipFile(z_name, 'w')
    z_file.write(j_name)
    z_file.write(e_name)
    os.remove(j_name)
    os.remove(e_name)
    z_file.close()
    # 再次读取zip文件,将文件流返回,但是此时打开方式要以二进制方式打开
    z_file = open(z_name, 'rb')
    data = z_file.read()
    z_file.close()
    os.remove(z_file.name)
    response = HttpResponse(data, content_type='application/zip')
    from urllib import parse
    response['Content-Disposition'] = 'attachment;filename=' + parse.quote(z_name)
    return response
  except Exception as e:
    logging.error(e)
    print(e)

Detaillierte Erläuterung der Schritte zur Verwendung der xe-utils-Funktionsbibliothek mit vue

vue2.0 Routing wird nicht angezeigt. Wie man mit der Router-Ansicht umgeht

Wie Native Fetch verwendet, um die Funktion zum Hochladen von Bildern zu implementieren

Das obige ist der detaillierte Inhalt vonSo implementieren Sie die Funktion zum Herunterladen von Dateien in Django. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn