乐趣区

关于django:DjangoDRF导出excel表格drfrendererxlsx的使用

前言

在 DRF 中,生成 excel 表格最不便的是借助第三方插件 drf-renderer-xlsx, 使得“导出”性能变得和写一般视图一样简略、不便、快捷。其思维是基于列表,毕竟 list 办法生成的 queryset 曾经和所须要的表格构造相似了,只是须要放在表格文件中。

版本

drf-renderer-xlsx==0.4.3
Django==3.1.4
djangorestframework==3.12.4

配置

将以下配置写入 REST_FRAMEWORK

REST_FRAMEWORK = {
    "DEFAULT_RENDERER_CLASSES": [
        "rest_framework.renderers.JSONRenderer",
        "rest_framework.renderers.BrowsableAPIRenderer",
        "drf_renderer_xlsx.renderers.XLSXRenderer",
    ],
}

视图

首先看一个简略的导出视图实现

from drf-renderer-xlsx import XLSXFileMixin
from drf-renderer-xlsx import XLSXRenderer
from rest_framework import viewsets, filters, mixins

class ExportViewSet(mixins.ListModelMixin, GenericViewSet, XLSXFileMixin):
    renderer_classes = (XLSXRenderer,)
    queryset = Model.objects.all()
    serializer_class = ExportSerializer
    xlsx_use_labels = True
  1. 导出视图就和一般的 list 视图相似,同时继承 ListModelMixin,GenericViewSet,以及咱们的配角 XLSXFileMixin
  2. renderer_classes 指定渲染器,必须要
  3. queryset 汇合
  4. serializer_class 序列化器
  5. xlsx_use_labels 默认为 False, 可要可不要,此属性的作用是设置表头的名称。默认是字段名,为 True 时,在 serializer 中 联合属性 label能够 指定表头名称为 label 值,例如
class ExportSerializer(serializers.Serializer):
    name = serializers.SerializerMethodField(label="姓名")

默认表头名称为“name”,为 True 时,名称为 ” 姓名 ”

再配置 url, 向 url 申请就能够取得一个 excel 表格。简略的配置就到这里。

小结

要实现导出表格性能,须要:

  1. 写入配置项
  2. 在 list 视图的根底上,继承 XLSXFileMixin,设置渲染器 renderer、汇合 queryset、序列化器
  3. 要想指定表头的名称,增加 xlsx_use_labels=True,同时在序列化器中申明字段的 label 值。默认为模型的字段名。

一些其余属性及性能

在开发导出性能的时候,咱们常常会遇到一些其余的性能需要,以下都是在 视图类中的设置

  1. 设置导出的文件名称

     filename = "my_export.xlsx"  # 设置属性 filename

    默认为 export.xlsx
    还能够通过编写办法去笼罩来设置文件名,办法名:get_filename()

  2. 疏忽字段

     xlsx_ignore_headers = [<fieldname>] # 疏忽的字段

    此属性是设置在视图类下的,疏忽字段也能够在序列化器中实现。(序列化器如果继承的是 Serializer 不申明就能够,如果是 ModelSerializer 能够应用,也能够通过重写序列化器中的 to_representation()办法。)

  3. 命名布尔值

     xlsx_boolean_labels = {True: _('Yes'), False: _('No')}

    将布尔值中的 True 替换为 Yes,False 替换为 No,也可在 serilaizer 中解决。

  4. 自定义映射——xlsx_custom_cols
    应用场景:就我集体来说目前遇到的应用场景是,数据库中的这个字段存储的时候就是以映射存储的,比方问卷调查的后果,每个用户的每道题答案是依据映射存储的,(比方 1,2,3)这样,导出的时候须要还原成选项文字。
def list(self, request, *args, **kwargs):
    .......
    for i in results:
        for k,v in i.items():
             self.xlsx_custom_cols.update({k: {"label": k, "formatter": v}})
     return Response(results)

results 就是表格对象。遍历,映射,更新字段值

  1. 与 DRF 的联合:筛选、权限、排序
class ExportViewSet(viewsets.ReadOnlyModelViewSet, XLSXFileMixin):
    authentication_classes = (JWTAuthentication,)                   # 认证
    filter_backends = (BaseFilterBackend, filters.OrderingFilter)  # 筛选
    filter_class = ExportFilter                                   # 筛选字段
    renderer_classes = (XLSXRenderer)                           # 渲染器
    permission_classes = (IsAuthenticated,)                  # 权限
    queryset = Model.objects.all()                            # 汇合
    serializer_class = ExportSerializer                          #序列化器
    xlsx_use_labels = True                                   # 表头名称替换

另外:
因为我的 Model 有很多状态字段须要保护,这些字段都是用带映射的 SmallIntegerField 字段做的,
在导出的时候,也须要输入映射值
例如:
model:

from django.utils.translation import gettext_lazy as _T

class Model(models.Model):
    class StatusChoices(models.IntegerChoices):
        PAID = 1, _T("已领取")
        REFUND = 2, _T("退款")
        REFUNDING = 3, _T("退款中")
        UNREFUND = 4, _T("未退款")
    
    status = models.SmallIntegerField(
        default=StatusChoices.PAID,
        help_text="订单状态",
        choices=StatusChoices.choices,
)

serializer:

class ExportSerilaizer(serializers.Serializer):
    status = serializers.SerializerMethodField(label="订单状态")

    def get_status(self, instance):
         return instance.get_status_display()

在序列化器中重写办法,前面跟_display(), 就能够使得字段输入为映射的中文值 > “ 已领取 ”\” 退款 ”

大部分对于字段值的更改,都能够在 serializer 中实现。

总结

第三方插件的应用,与 DRF、Django 的纯熟联合,能够使得需要实现变得多计划、更简便。开发学习中,理解源码还是比拟重要的。

参考

drf-renderer-xlsx 文档

退出移动版