可用性比之前上了一个台阶, 欢迎大家使用, 也欢迎提意见和建议, 谢谢!
项目地址: https://github.com/oddcc/django-export-csv
=======================================================
Django 的一个 CSV 导出工具 可以很方便的把 queryset 导出为 CSV 文件, 为了避免导出文件过大, 占用服务器内存, 生成的是 StreamingHttpResponset.
支持通过下面几种方式对导出的 CSV 文件进行定制
Run:
pip install django-export-csv
Support Python 2.7 and 3.5, Django >= 1.8.
使用 CBV 的话, 视图类需要继承ListView
(或MultipleObjectMixin
的子类)和QueryCsvMixin
, 继承之后就可以调用render_csv_response
方法把 queryset 导出为 CSV 文件, render_csv_response
方法需要一个QuerySet
或ValuesQuerySet
的实例作为参数:
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)
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)
视图类继承了 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
)
1
corningsun 2017-05-23 14:01:15 +08:00
不错不错
最近有个需求,也是需要导出数据。不过不是直接导出固定的表和字段,render_csv_response 方法能不能接收一个非 queryset 对象? |
2
oddcc OP @corningsun 目前不能..
|
3
prasanta 2017-05-23 14:31:07 +08:00
请问在什么情况下我会使用这个呢
|
5
clampist 2017-05-23 19:05:40 +08:00 via iPhone
感谢分享,很实用啊
|
6
uhayate 2017-05-24 09:38:23 +08:00 via iPhone 1
东西不错,不过看到介绍还是有点懵逼。能写一下应用场景这样最好,举几个例子,这样大家可能更了解它。
|
8
lovesecho 2017-05-26 11:55:50 +08:00
django-import-export==0.5.1 目前在用这个,数据不大的话貌似也还凑合。
|