Python中常用Django的同学看过来, 个人开源的小工具更新啦
- 此次更新了中文文档...
- 增加了 FBV 的调用方式
- 支持 Many-to-Many, Many-to-One, One-to-Many 的关系导出
- 支持了 extra 和 annotate 的复杂查询
可用性比之前上了一个台阶, 欢迎大家使用, 也欢迎提意见和建议, 谢谢!
项目地址: https://github.com/oddcc/django-export-csv
=======================================================
django-export-csv
Introduction
Django 的一个 CSV 导出工具 可以很方便的把 queryset 导出为 CSV 文件, 为了避免导出文件过大, 占用服务器内存, 生成的是 StreamingHttpResponset.
支持通过下面几种方式对导出的 CSV 文件进行定制
- 文件名
- 导出的时候文件名加 /不加时间戳
- 表头是不是使用 verbose_name
- 可以排除不想导出的字段
- 自定义导出字段的顺序
- 自定义表头
- 自定义字段的表现形式(serializer)
- 支持导出外键, 多对多, 外键反向查询这些关系, 需要自定义
install
Run:
pip install django-export-csv
Support Python 2.7 and 3.5, Django >= 1.8.
usage
使用 CBV 的话, 视图类需要继承ListView(或MultipleObjectMixin的子类)和QueryCsvMixin, 继承之后就可以调用render_csv_response方法把 queryset 导出为 CSV 文件, render_csv_response方法需要一个QuerySet或ValuesQuerySet的实例作为参数:
使用 CBV
from django_export_csv import QueryCsvMixin
from django.views.generic.list import ListView
from .models import Student
class StudentListView(QueryCsvMixin, ListView):
queryset = Student.objects.all()
def get(self, *args, **kwargs):
return self.render_csv_response(queryset)
使用 FBV
from django_export_csv import render_csv_response
def student_list_view(request):
if request.method == ‘GET’:
queryset = Student.objects.all()
return render_csv_response(queryset)
定制 CSV
视图类继承了 QueryCsvMixin之后, 就可以使用以下参数自定义 CSV 文件:
filename- (default:None), 是个字符串, 如果不定义, CSV 会根据 model 来生成文件名.add_datestamp- (default:False), 是个布尔值, 如果为 True 的话, 导出的文件名末尾会添加当前时间的时间戳.use_verbose_names- (default:True), 是个布尔值, 如果设为 True, CSV 表头的名称会使用 model 中定义的 verbose_name.exclude_field- (default:[]), 是个包含了不想导出的字段名的列表, 不设的话, 默认导出所有字段.field_order- (default:[]), 是个列表, 可以把想定义排序的字段名写在里面, 导出的 CSV 会优先按顺序排列这个参数指定的字段, 再排剩下的字段.field_header_map- (default:{}), 是个字典, 用于自定义表头, key 应该是字段名, value 是表头中显示的内容, 这个参数的优先级比 verbose_name 高.field_serializer_map- (default:{}), 是个字典, 用于自定义 serializer, key 是字段名, value 是对应的函数名, 这个函数应该接收一个值并返回相应的内容.extra_field- (default:[]), 是个列表, 用于定义不在数据库表中但又与 model 相关的字段, 比如外键的反向查询, 多对多关系等等, 也可以用于定义任意其他跟 model 相关的字段. 注意如果指定了extra_field参数,field_serializer_map中必须有相应的 serializer 配合才能工作.
e.g:
# data_init.py
import datetime
from .models import Student, College
def create_student_and_get_queryset():
college1, _ = College.objects.get_or_create(name=“College 1st”)
college2, _ = College.objects.get_or_create(name=“College 2nd”)
Student.objects.get_or_create(
name='Jim', age=18, is_graduated=False, birthday=datetime.date(1998,6,6), college=college1
)
Student.objects.get_or_create(
name='Bing', age=22, is_graduated=True, birthday=datetime.date(1994, 2, 6), college=college1
)
Student.objects.get_or_create(
name='Monica', age=25, is_graduated=True, birthday=datetime.date(1991, 2, 6), college=college2
)
return Student.objects.all()
# views.py
from django_export_csv import QueryCsvMixin
from django_export_csv import render_csv_response
from django.views.generic.list import ListView
from .models import Student
from .data_init import create_student_and_get_queryset
def boolean_serializer(value):
if value == True:
return 'Y'
else:
return 'N'
def college_serializer(obj):
return obj.college.name
# CBV
class StudentListView(QueryCsvMixin, ListView):
filename = 'export_student_list'
add_datestamp = True
use_verbose_names = True
exclude_field = ['id']
field_order = ['name', 'is_graduated']
field_header_map = {'is_graduated': 'Graduated'}
field_serializer_map = {'is_graduated': boolean_serializer, 'college': college_serializer}
queryset = Student.objects.all()
extra_field = ['college']
def get(self, *args, **kwargs):
queryset = create_student_and_get_queryset()
return self.render_csv_response(queryset)
# FBV
def student_list_view(request):
filename = 'export_student_list'
add_datestamp = True
use_verbose_names = True
exclude_field = ['id']
field_order = ['name', 'is_graduated']
field_header_map = {'is_graduated': 'Graduated'}
field_serializer_map = {'is_graduated': boolean_serializer, 'college': college_serializer}
extra_field = ['college']
if request.method == 'GET':
queryset = create_student_and_get_queryset()
return render_csv_response(
queryset, filename=filename, add_datestamp=add_datestamp, use_verbose_names=use_verbose_names,
exclude_field=exclude_field, field_order=field_order, field_header_map=field_header_map,
field_serializer_map=field_serializer_map, extra_field=extra_field
)
Python中常用Django的同学看过来, 个人开源的小工具更新啦
不错不错
最近有个需求,也是需要导出数据。不过不是直接导出固定的表和字段,render_csv_response 方法能不能接收一个非 queryset 对象?
我无法理解你的问题
目前不能…
请问在什么情况下我会使用这个呢
各种管理系统中会用的多一点吧, 主要是公司里很多类似的导出需求, 用这个就方便多了
感谢分享,很实用啊
东西不错,不过看到介绍还是有点懵逼。能写一下应用场景这样最好,举几个例子,这样大家可能更了解它。
谢谢建议, 确实介绍中应该包括应用场景…楼上的同学也是提到这一点
django-import-export==0.5.1 目前在用这个,数据不大的话貌似也还凑合。

