django下載csv檔案筆記

a599174211發表於2018-09-21

下載小的csv檔案

這裡將用一個生成小的CSV檔案為例,來把生成CSV檔案的技術要點講到位。我們用Python內建的csv模組來處理csv檔案,並且使用HttpResponse來將csv檔案返回回去。示例程式碼如下:


1.在templates目錄下新建一個abc.txt的檔案模板,內容如下

{% for row in rows%}{{row.0}},{{row.1}}
{% endfor %}

2.在view檢視中編寫如下程式碼

from django.shortcuts import render,loader
from django.http import HttpResponse,StreamingHttpResponse
import csv
def csvtest(request):
    #設定型別為csv
    response = HttpResponse(content_type='text/csv')
    #設定Content-Disposition屬性,檔名為abc.csv
    response['Content-Disposition'] = "attachment;filename='abc.csv'"
    context = {
        'rows':[['username', 'age'],
                ['age', 18]]
    }
    render_csv = render(request, 'abc.txt',context=context)
    response.content = render_csv

    #或者使用csv寫入內容
    # writer = csv.writer(response)
    # writer.writerow(['username', 'age'])
    # writer.writerow(['zhiliao', '18'])
    
    return response

這裡再來對每個部分的程式碼進行解釋:

  1. 我們在初始化HttpResponse的時候,指定了Content-Typetext/csv,這將告訴瀏覽器,這是一個csv格式的檔案而不是一個HTML格式的檔案,如果用預設值,預設值就是html,那麼瀏覽器將把csv格式的檔案按照html格式輸出,這肯定不是我們想要的。
  2. 第二個我們還在response中新增一個Content-Disposition頭,這個東西是用來告訴瀏覽器該如何處理這個檔案,我們給這個頭的值設定為attachment;,那麼瀏覽器將不會對這個檔案進行顯示,而是作為附件的形式下載,第二個filename="abc.csv"是用來指定這個csv檔案的名字。
  3. 我們使用response.content設定response的內容

 


下載大的csv檔案

以上的例子是生成的一個小的csv檔案,如果想要生成大型的csv檔案,那麼以上方式將有可能會發生超時的情況(伺服器要生成一個大型csv檔案,需要的時間可能會超過瀏覽器預設的超時時間)。這時候我們可以藉助另外一個類,叫做StreamingHttpResponse物件,這個物件是將響應的資料作為一個流返回給客戶端,而不是作為一個整體返回。示例程式碼如下:

from django.shortcuts import render,loader
from django.http import HttpResponse,StreamingHttpResponse
def large_csv(request):
    response = StreamingHttpResponse(content_type='text/csv')
    response['content-Disposition']= "attachment;filename='lange.csv'"
    rows = ('Row{},{}/n'.format(row, row) for row in range(0,1000000))
    response.streaming_content = rows
    return response

這個類是專門用來處理流資料的。使得在處理一些大型檔案的時候,不會因為伺服器處理時間過長而到時連線超時。這個類不是繼承自HttpResponse,並且跟HttpResponse對比有以下幾點區別:

  1. 這個類沒有屬性content,相反是streaming_content
  2. 這個類的streaming_content必須是一個可以迭代的物件。
  3. 這個類沒有write方法,如果給這個類的物件寫入資料將會報錯。

注意:StreamingHttpResponse會啟動一個程式來和客戶端保持長連線,所以會很消耗資源。所以如果不是特殊要求,儘量少用這種方法。

相關文章