Django Admin 后台增加 导出数据到 CSV

在Django Admin中每个模型的Admin类(继承至admin.ModelAdmin), 我们可以通过actions增加支持的动作, 值为当前类存在的方法名, 例如:

Python
@admin.register(Issue) class IssueAdmin(admin.ModelAdmin): ...... actions = ['export_as_csv'] # 增加动作, 对应相应的方法名 def export_as_csv(self, request, queryset): # 具体的导出csv方法的实现 pass export_as_csv.short_description = '导出CSV' # 该动作在admin中的显示文字 导出CSV方法详细实现如下: def export_as_csv(self, request, queryset): meta = self.model._meta # 用于确定导出的文件名, 格式为: app名.模型类名 field_names = [field.name for field in meta.fields] # 所有属性名 response = HttpResponse(content_type='text/csv') # 指定响应内容类型 response['Content-Disposition'] = f'attachment; filename={meta}.csv' response.charset = 'utf-8-sig' # 可选, 修改编码为带BOM的utf-8格式(Excel打开不会有乱码) writer = csv.writer(response) writer.writerow(field_names) # 将属性名写入csv for obj in queryset: # 遍历要导出的对象列表 row = writer.writerow([getattr(obj, field) for field in field_names]) # 将当前对象的各属性值写入csv return response
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@ admin . register ( Issue )
class IssueAdmin ( admin . ModelAdmin ) :
     . . . . . .
     actions = [ 'export_as_csv' ]    # 增加动作, 对应相应的方法名
     def export_as_csv ( self , request , queryset ) :    # 具体的导出csv方法的实现
         pass
 
     export_as_csv . short_description = '导出CSV'    # 该动作在admin中的显示文字
导出 CSV方法详细实现如下 :
 
     def export_as_csv ( self , request , queryset ) :
         meta = self . model . _meta    # 用于确定导出的文件名, 格式为: app名.模型类名
         field_names = [ field . name for field in meta . fields ]    # 所有属性名
 
         response = HttpResponse ( content_type = 'text/csv' )    # 指定响应内容类型
         response [ 'Content-Disposition' ] = f 'attachment; filename={meta}.csv'
         response . charset = 'utf-8-sig'    # 可选, 修改编码为带BOM的utf-8格式(Excel打开不会有乱码)
         writer = csv . writer ( response )
         writer . writerow ( field_names )    # 将属性名写入csv
         for obj in queryset :    # 遍历要导出的对象列表
             row = writer . writerow ( [ getattr ( obj , field ) for field in field_names ] )    # 将当前对象的各属性值写入csv
         return response
 

由于导出CSV动作可以作为各个模型的通用动作, 我们可以封装成一个Mixin类使用, 完整代码如下:

Python
import csv from <span class="wp_keywordlink_affiliate"><a href="https://www.168seo.cn/tag/django" title="View all posts in django" target="_blank">django</a></span>.contrib import admin from <span class="wp_keywordlink_affiliate"><a href="https://www.168seo.cn/tag/django" title="View all posts in django" target="_blank">django</a></span>.http import HttpResponse from .models import Issue class ExportCsvMixin(object): def export_as_csv(self, request, queryset): meta = self.model._meta field_names = [field.name for field in meta.fields] response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = f'attachment; filename={meta}.csv' response.charset = 'utf-8-sig' writer = csv.writer(response) writer.writerow(field_names) for obj in queryset: row = writer.writerow([getattr(obj, field) for field in field_names]) return response export_as_csv.short_description = '导出CSV' @admin.register(Issue) class IssueAdmin(admin.ModelAdmin, ExportCsvMixin): fields = ('key', 'summary', 'status', 'project', 'origin', 'components', 'prj_level', 'prj_category', 'assignee', 'origin_person', 'pm', 'dev_manager', 'test_manager', 'tester', 'fe_dev', 'backend_dev', 'plan_begin', 'plan_end', 'fe_plan_begin', 'fe_plan_end', 'test_plan_begin', 'test_plan_end', 'backend_plan_begin', 'backend_plan_end', 'created', 'reopen', 'prd_begin', 'prd_end', 'dev_begin', 'dev_end', 'test_begin', 'test_end', 'pm_check', 'ready', 'pause', 'done', 'pm_take', 'dev_take', 'test_take', 'total_take', 'tags', ) readonly_fields = fields list_display = ('key', 'summary', 'status', 'origin', 'components', 'created', 'visit') list_filter = ('origin', 'components', 'status', 'tags') search_fields = ('key', 'summary') date_hierarchy = 'created' actions = ['export_as_csv']
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import csv
from django . contrib import admin
from django . http import HttpResponse
from . models import    Issue
 
class ExportCsvMixin ( object ) :
     def export_as_csv ( self , request , queryset ) :
         meta = self . model . _meta
         field_names = [ field . name for field in meta . fields ]
 
         response = HttpResponse ( content_type = 'text/csv' )
         response [ 'Content-Disposition' ] = f 'attachment; filename={meta}.csv'
         response . charset = 'utf-8-sig'
         writer = csv . writer ( response )
         writer . writerow ( field_names )
         for obj in queryset :
             row = writer . writerow ( [ getattr ( obj , field ) for field in field_names ] )
 
         return response
 
     export_as_csv . short_description = '导出CSV'
 
@ admin . register ( Issue )
class IssueAdmin ( admin . ModelAdmin , ExportCsvMixin ) :
     fields = ( 'key' , 'summary' , 'status' , 'project' ,
               'origin' , 'components' , 'prj_level' , 'prj_category' ,
               'assignee' , 'origin_person' , 'pm' , 'dev_manager' , 'test_manager' , 'tester' , 'fe_dev' , 'backend_dev' ,
               'plan_begin' , 'plan_end' , 'fe_plan_begin' , 'fe_plan_end' , 'test_plan_begin' ,
               'test_plan_end' , 'backend_plan_begin' , 'backend_plan_end' ,
               'created' , 'reopen' , 'prd_begin' , 'prd_end' , 'dev_begin' , 'dev_end' ,
               'test_begin' , 'test_end' , 'pm_check' , 'ready' , 'pause' , 'done' ,
               'pm_take' , 'dev_take' , 'test_take' , 'total_take' ,
               'tags' ,
               )
     readonly_fields = fields
     list_display = ( 'key' , 'summary' , 'status' , 'origin' , 'components' , 'created' , 'visit' )
     list_filter = ( 'origin' , 'components' , 'status' , 'tags' )
     search_fields = ( 'key' , 'summary' )
     date_hierarchy = 'created'
     actions = [ 'export_as_csv' ]
 



  • zeropython 微信公众号 5868037 QQ号 5868037@qq.com QQ邮箱
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值