当前位置: 首页 > 后端技术 > Python

django-DRF导出excel表格,drf-renderer-xlsx的使用

时间:2023-03-25 19:59:05 Python

前言在DRF中,生成excel表格最方便的方法就是使用第三方插件drf-renderer-xlsx,它使得“导出”功能类似于编写普通视图一样简单、方便、快捷。这个想法是基于列表。毕竟list方法生成的queryset已经和需要的表结构类似了,只是需要放在表文件中。versiondrf-renderer-xlsx==0.4.3Django==3.1.4djangorestframework==3.12.4配置将如下配置写入REST_FRAMEWORKREST_FRAMEWORK={"DEFAULT_RENDERER_CLASSES":["rest_framework.renderers.JSONRenderer","rest_framework.renderers.BrowsableAPIRenderer","drf_renderer_xlsx.renderers.XLSXRenderer",],}视图首先看一个简单的导出视图实现ExportViewSet(mixins.ListModelMixin,,XLSXFileMixin):renderer_classes=(XLSXRenderer,)queryset=Model.objects.all()serializer_class=ExportSerializerxlsx_use_labels=True导出的视图类似于普通的列表视图,同时继承了ListModelMixin、GenericViewSet和我们的主角XLSXFileMixinrenderer_classes指定渲染器,必须有querysetsetserializer_classserializerxlsx_use_labels默认为False,可选与否,r该属性的ole是设置表头的名称。默认为字段名称。为True时,header名称可以在serializer中结合属性label指定为label值。例如classExportSerializer(serializers.Serializer):name=serializers.SerializerMethodField(label="name")默认的headername为当"name"为True时,name为"name"然后配置url,一个excel表格可以通过请求url获取。简单的配置在这里。总结要实现导出表的功能,需要:基于列表视图编写配置项,继承XLSXFileMixin,设置renderer、collectionqueryset、serializer。要指定表头的名称,添加xlsx_use_labels=True,同时在序列优化器中声明字段的标签值。默认为模型的字段名称。一些其他的属性和功能在开发导出功能的时候,我们经常会遇到一些其他的功能需求。以下是视图类中的设置。设置导出文件名filename="my_export.xlsx"#设置属性文件名默认为export.xlsx。也可以通过写一个方法覆盖来设置文件名,方法名:get_filename()ignorefieldxlsx_ignore_headers=[]#ignore字段的这个属性在视图类下设置,被忽略的字段也可以在序列化器中实现。(如果serializer继承自Serializer,则可以不声明使用,如果是ModelSerializer,则可以使用,或者通过重写serializer中的to_representation()方法。)namedbooleanvaluexlsx_boolean_labels={True:_('Yes'),False:_('No')}Boolean中的True换成Yes,False换成No,也可以在serilaizer中处理。自定义映射-xlsx_custom_cols使用场景:个人目前遇到的使用场景是,数据库中这个字段存储的时候,存储为一个映射,比如问卷调查的结果,每个用户对每个问题的回答它是根据映射存储的,(比如1、2、3)。这样导出的时候需要恢复成选项文本。deflist(self,request,*args,**kwargs):......foriinresults:fork,vini.items():self.xlsx_custom_cols.update({k:{"标签":k,"formatter":v}})returnResponse(results)results就是表格对象。结合DRF遍历、映射、更新字段值:过滤、权限、排序类=ExportFilter#Filterfieldrenderer_classes=(XLSXRenderer)#rendererpermission_classes=(IsAuthenticated,)#permissionqueryset=Model.objects.all()#collectionserializer_class=ExportSerializer#serializerxlsx_use_labels=True#表头名称替换另外:由于我Model有很多状态字段需要维护。这些字段都是由带映射的SmallIntegerField字段组成的。导出时,还需要输出映射值。例如:model:fromdjango.utils.translationimportgettext_lazyas_TclassModel(models.Model):classStatusChoices(models.IntegerChoices):PAID=1,_T("Paid")REFUND=2,_T("Refunded")退款=3,_T("Refunding")UNREFUND=4,_T("NotRefunded")status=models.SmallIntegerField(default=StatusChoices.PAID,help_text="订单状态",choices=StatusChoices.choices,)serializer:classExportSerilaizer(serializers.Serializer):status=serializers.SerializerMethodField(label="orderstatus")defget_status(self,instance):returninstance.get_status_display()重写serializer中的方法,后面是_display(),可以让字段输出为mappedChinesevalue>"Paid"\"Refund"大部分关于字段值的改变都可以在serializer中实现,总结一下第三方插件的使用,与DRF和Django的熟练结合可以使需求实现变得多方案更容易,在开发和学习中,更重要的是看懂源码,参考drf-renderer-xlsx文档