在Django Admin中每个模型的Admin类(继承至admin.ModelAdmin), 我们可以通过actions增加支持的动作, 值为当前类存在的方法名, 例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@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类使用, 完整代码如下:
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 |
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'] |

增加导出 text 功能
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 |
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: writer.writerow([getattr(obj, field) for field in field_names]) return response export_as_csv.short_description = '导出CSV' class ExportTxtMixin(object): def export_as_txt(self,request,queryset): meta = self.model._meta field_names = [field.name for field in meta.fields] response = HttpResponse(content_type='text/plain') response['Content-Disposition'] = f'attachment; filename={meta}.txt' for obj in queryset: response.write(",".join([str(getattr(obj, field)) for field in field_names])+"\n") return response export_as_txt.short_description = "导出到 TXT" @admin.register(Crawled_article) class Crawled_articleAdmin(admin.ModelAdmin,ExportCsvMixin,ExportTxtMixin): ordering = ("id",) list_display = ("id","title","title_url") list_display_links = ("title_url",) actions = ['export_as_csv',"export_as_txt"] # 增加动作, 对应相应的方法名 |
