日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

更高效的Python CSV文件導(dǎo)出

 鷹兔牛熊眼 2019-01-17

閱讀本文大概需要6分鐘

在上一篇文章,我介紹了CSV是什么?CSV有哪些優(yōu)點(diǎn)?如何使用等等?并且最后我們用一個(gè)例子簡(jiǎn)單講解了如何使用Python模塊CSV進(jìn)行導(dǎo)出后綴為.csv的文本文件。

具體文章參看:Python模塊之CSV導(dǎo)出(一)

其實(shí)例子用于異步導(dǎo)出數(shù)據(jù)文件是夠了,但工作中我們可能還需要結(jié)合我們Web框架進(jìn)行更復(fù)雜的CSV導(dǎo)出。

所以今天我們的目的就是結(jié)合Python Django框架進(jìn)行分享CSV導(dǎo)出的另外一種方式。

安裝依賴

這里面我們需要安裝一個(gè)第三方包djangorestframework-csv
方法如下,使用pip安裝到你virtualenv構(gòu)建的虛擬環(huán)境中,當(dāng)然你如果使用了docker進(jìn)行環(huán)境隔離這兒也可以直接安裝你docker容器中。

$ pip install djangorestframework-csv

有些同學(xué)可能不太明白,明明是Django框架怎么和Django REST Framework(簡(jiǎn)稱DRF)扯上關(guān)系了,簡(jiǎn)單解釋一下,由于我們Django API開發(fā)常常配合DRF進(jìn)行,所以一般都是一起安裝使用了的,把Django和DRF結(jié)合起來整個(gè)RESTFul API開發(fā)效率能大大提高,建議稍微大一點(diǎn)工程化項(xiàng)目都去使用DRF。

使用

使用方式如下:

  1. 繼承CSVRenderer 定義一個(gè)自己的Render類

  2. 將要生成CSV的字典數(shù)據(jù)傳入該類的方法render方法

  3. 使用HttpResponse或者StreamingHttpResponse進(jìn)行返回

看起來是不是簡(jiǎn)單方便,確實(shí)就是這么簡(jiǎn)單,下面我們看一個(gè)例子。

例子

廢話不多說,直接上代碼,先定義一個(gè)自己的CSV Render

# 定義CSV Renderfrom rest_framework_csv import renderersclass YourModelRender(renderers.CSVStreamingRenderer):    header = [        'phone',        'remark',        'create_time',    ]    labels = dict([        ('phone', u'聯(lián)系電話'),        ('remark', u'備注'),        ('create_time', u'時(shí)間'),    ])

這里使用label dict屬性將自定義標(biāo)簽應(yīng)用于CSVRenderer,其中每個(gè)鍵對(duì)應(yīng)于表頭header,值對(duì)應(yīng)于該表頭header的自定義標(biāo)簽,這樣我們各個(gè)值就能和header對(duì)應(yīng)起來。

Django導(dǎo)出的view方法,源碼如下。

    @list_route(methods=['get']) # 這是DRF生成URL的方式,沒用過的可以忽略。    def example_export_csv(self):        '''        CSV 案例        '''        queryset = YourModel.objects.all()        renderer = YourModelRender()        data = (            YourModelListSerializer(instance).data ## 得到字典數(shù)據(jù)            for instance in queryset        )        response = StreamingHttpResponse(            renderer.render(data),            content_type='text/csv'        )        response['Content-Disposition'] = 'attachment; filename='somefilename.csv''        return response

上面幾行代碼是不是看起來很簡(jiǎn)單,確實(shí)就是這么簡(jiǎn)單,簡(jiǎn)單的背后是rest_framework_csv幫我們做了導(dǎo)出功能,底層實(shí)現(xiàn)還是昨天我說的那種方式write,writerow的方式。

這里面簡(jiǎn)單解釋一下:

  1. YourModelListSerializer寫過DRF的同學(xué)知道這個(gè)就是定義數(shù)據(jù)處理邏輯校驗(yàn),格式化什么等操作。這里面我們通過YourModelListSerializer復(fù)用了其他模塊處理邏輯,如RRESTFul的列表數(shù)據(jù)展示。

  2. 這樣大大減少了我們導(dǎo)出CSV還需要去重新處理多個(gè)字段組裝,過濾,變換等邏輯。因?yàn)橥覀兞斜硇枰故緮?shù)據(jù)就是我們CSV要導(dǎo)出的數(shù)據(jù)。記得幾年前那會(huì)兒導(dǎo)出數(shù)據(jù)還要自己重新組裝數(shù)據(jù),真是酸爽。

  3. 我們這兒用了StreamingHttpResponse,將文件內(nèi)容進(jìn)行流式傳輸,對(duì)于實(shí)時(shí)導(dǎo)出大文件,可以避免服務(wù)器斷開連接。比起HttpResponse更節(jié)約內(nèi)存。

 其他

上面我們使用DRF,并且也用了看起來復(fù)雜的YourModelListSerializer這種復(fù)雜的概念,主要目的是讓大家知道DRF的方式,至于普通使用Django其實(shí)我們完全可以把renderer.render(data)換為上一篇文章
(writer.writerow(row) for row in rows) 這種形勢(shì)。

關(guān)于CSV我們還可以用Django模板形式進(jìn)行,和我們用rest_framework_csv模塊思路差不多
簡(jiǎn)單給一個(gè)官方案例:

csv_data = (        ('First row', 'Foo', 'Bar', 'Baz'),        ('Second row', 'A', 'B', 'C', ''Testing'', 'Here's a quote'),    )    t = loader.get_template('my_template_name.txt') # 定義模板代碼    c = Context({        'data': csv_data,    })response.write(t.render(c))return response

雖然思路相似,但過程實(shí)現(xiàn)會(huì)麻煩較多,你要去切換模板代碼書寫,渲染,不推薦這種方式。


最后關(guān)于CSV我們就介紹到這里,結(jié)合上一篇主要兩種方式:

  1. 普通CSV導(dǎo)出+Celery Beat定時(shí)導(dǎo)出

  2. Django + DRF + 實(shí)時(shí)導(dǎo)出

原理都是Python內(nèi)置模塊CSV的一些變換,只是結(jié)合第三庫,讓我們操作更快更方便起來。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多