
可用性比之前上了一个台阶, 欢迎大家使用, 也欢迎提意见和建议, 谢谢!
项目地址: 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': bolean_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 东西不错,不过看到介绍还是有点懵逼。能写一下应用场景这样最好,举几个例子,这样大家可能更了解它。 |
8 lovesecho 2017-05-26 11:55:50 +08:00 django-import-export==0.5.1 目前在用这个,数据不大的话貌似也还凑合。 |