在Django裏,流式響應StreamingHttpResponse
是個好東西,能夠快速、節省內存地產生一個大型文件。python
目前項目裏用於流式響應的一個是Eventsource
,用於改善跨系統通信時用戶產生的慢速的感受。這個不細說了。web
還有一個就是生成一個大的csv文件。django
當Django進程處於gunicorn或者uwsgi等web容器中時,若是響應超過必定時間沒有返回,就會被web容器終止掉,雖然咱們能夠經過加長web容器的超時時間來繞過這個問題,可是畢竟仍是治標不治本。要根本上解決這個問題,Python的生成器、Django框架提供的StreamingHttpResponse
這個流式響應頗有幫助框架
而在csv中,中文的處理也相當重要,要保證用excel打開csv不亂碼什麼的。。爲了節約空間,我就把全部代碼貼到一塊兒了。。實際使用按照項目的規劃放置哈excel
上代碼:code
pythonfrom __future__ import absolute_import import csv import codecs import cStringIO class Echo(object): def write(self, value): return value class UnicodeWriter: """ A CSV writer which will write rows to CSV file "f", which is encoded in the given encoding. """ def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): # Redirect output to a queue self.queue = cStringIO.StringIO() self.writer = csv.writer(self.queue, dialect=dialect, **kwds) self.stream = f self.encoder = codecs.getincrementalencoder(encoding)() def writerow(self, row): self.writer.writerow([handle_column(s) for s in row]) # Fetch UTF-8 output from the queue ... data = self.queue.getvalue() data = data.decode("utf-8") # ... and reencode it into the target encoding data = self.encoder.encode(data) # write to the target stream value = self.stream.write(data) # empty queue self.queue.truncate(0) return value def writerows(self, rows): for row in rows: self.writerow(row) from django.views.generic import View from django.http.response import StreamingHttpResponse class ExampleView(View): headers=['一些','表頭'] def get(self,request): result = [['第一行','數據1'], ['第二行','數據2']] echoer = Echo() writer = UnicodeWriter(echoer) def csv_itertor(): yield codecs.BOM_UTF8 yield writer.writerow(self.headers) for column in result: yield writer.writerow(column) response = StreamingHttpResponse( (row for row in csv_itertor()), content_type="text/csv;charset=utf-8") response['Content-Disposition' ] = 'attachment;filename="example.csv"' return response