Board logo

标题: 更高效的Python CSV文件导出(1) [打印本页]

作者: look_w    时间: 2019-4-12 16:11     标题: 更高效的Python CSV文件导出(1)

安装依赖

这里面我们需要安装一个第三方包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更节约内存。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0