python输出csv文件-更高效的Python CSV文件导出

1dabd328c3b2

image

在上一篇文章,我介绍了CSV是什么?CSV有哪些优点?如何使用等等?并且最后我们用一个例子简单讲解了如何使用Python模块CSV进行导出后缀为.csv的文本文件。

其实例子用于异步导出数据文件是够了,但工作中我们可能还需要结合我们Web框架进行更复杂的CSV导出。

所以今天我们的目的就是结合Python Django框架进行分享CSV导出的另外一种方式。

安装依赖

这里面我们需要安装一个第三方包djangorestframework-csv:

方法如下,使用pip安装到你virtualenv构建的虚拟环境中,当然你如果使用了docker进行环境隔离这儿也可以直接安装你docker容器中。

$ pip install djangorestframework-csv

有些同学可能不太明白,明明是Django框架怎么和Django REST Framework(简称DRF)扯上关系了,简单解释一下,由于我们Django API开发常常配合DRF进行,所以一般都是一起安装使用了的,把Django和DRF结合起来整个RESTFul API开发效率能大大提高,建议稍微大一点工程化项目都去使用DRF。

使用

使用方式如下:

继承CSVRenderer 定义一个自己的Render类

将要生成CSV的字典数据传入该类的方法render方法

使用HttpResponse或者StreamingHttpResponse进行返回

看起来是不是简单方便,确实就是这么简单,下面我们看一个例子。

例子

废话不多说,直接上代码,先定义一个自己的CSV Render

# 定义CSV Render

from rest_framework_csv import renderers

class YourModelRender(renderers.CSVStreamingRenderer):

header = [

'phone',

'remark',

'create_time',

]

labels = dict([

('phone', u'联系电话'),

('remark', u'备注'),

('create_time', u'时间'),

])

这里使用label dict属性将自定义标签应用于CSVRenderer,其中每个键对应于表头header,值对应于该表头header的自定义标签,这样我们各个值就能和header对应起来。

Django导出的view方法,源码如下。

@list_route(methods=['get']) # 这是DRF生成URL的方式,没用过的可以忽略。

def example_export_csv(self):

'''

CSV 案例

'''

queryset = YourModel.objects.all()

renderer = YourModelRender()

data = (

YourModelListSerializer(instance).data ## 得到字典数据

for instance in queryset

)

response = StreamingHttpResponse(

renderer.render(data),

content_type='text/csv'

)

response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'

return response

上面几行代码是不是看起来很简单,确实就是这么简单,简单的背后是rest_framework_csv帮我们做了导出功能,底层实现还是昨天我说的那种方式write,writerow的方式。

这里面简单解释一下:

YourModelListSerializer写过DRF的同学知道这个就是定义数据处理逻辑校验,格式化什么等操作。这里面我们通过YourModelListSerializer复用了其他模块处理逻辑,如RRESTFul的列表数据展示。

这样大大减少了我们导出CSV还需要去重新处理多个字段组装,过滤,变换等逻辑。因为往往我们列表需要展示数据就是我们CSV要导出的数据。记得几年前那会儿导出数据还要自己重新组装数据,真是酸爽。

我们这儿用了StreamingHttpResponse,将文件内容进行流式传输,对于实时导出大文件,可以避免服务器断开连接。比起HttpResponse更节约内存。

其他

上面我们使用DRF,并且也用了看起来复杂的YourModelListSerializer这种复杂的概念,主要目的是让大家知道DRF的方式,至于普通使用Django其实我们完全可以把renderer.render(data)换为上一篇文章

(writer.writerow(row) for row in rows) 这种形势。

关于CSV我们还可以用Django模板形式进行,和我们用rest_framework_csv模块思路差不多

简单给一个官方案例:

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

虽然思路相似,但过程实现会麻烦较多,你要去切换模板代码书写,渲染,不推荐这种方式。

最后关于CSV我们就介绍到这里,结合上一篇主要两种方式:

普通CSV导出+Celery Beat定时导出

Django + DRF + 实时导出

原理都是Python内置模块CSV的一些变换,只是结合第三库,让我们操作更快更方便起来。

1dabd328c3b2

image

扫码免费加入我们

更多阅读:

1dabd328c3b2

image

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值