如何在Django REST framework中实现PDF、Excel导出自定义渲染器并设置文件名
问题解答
1. renderer_classes配置说明
你在视图中配置的renderer_classes是正确的,Django REST Framework会自动根据请求的Accept头或format查询参数匹配对应的渲染器,返回对应格式的响应。
2. 设置导出文件名的两种方案
方案一:在自定义渲染器内部设置(更推荐)
这种方式不需要修改视图逻辑,也不会影响普通JSON响应的头信息,适配性更强。你可以直接通过renderer_context拿到响应对象,设置Content-Disposition头即可,修改后的渲染器代码示例:
# app/renderers.py class PDFRenderer(BaseRenderer): media_type = 'application/pdf' format = 'pdf' charset = 'utf-8' def render(self, data, accepted_media_type=None, renderer_context=None): if hasattr(data, 'items'): for key, value in data.items(): if key == 'results': html_string = render_to_string('user_mbe/EmployeeList.html', {'header': ('first_name', 'last_name', 'id_number', 'phone_number', 'email', 'job_title'), 'data': [tuple(x.values()) for x in value]}) result = pdfkit.from_string(html_string, output_path=False, configuration=config) # 新增设置响应头代码 response = renderer_context['response'] response['Content-Disposition'] = 'attachment; filename="员工列表.pdf"' return result return None class XLSXRenderer(BaseRenderer): # ... 其余代码不变 def render(self, data, accepted_media_type=None, renderer_context=None): # ... 你原有生成Excel的逻辑 # 新增设置响应头代码 response = renderer_context['response'] response['Content-Disposition'] = 'attachment; filename="员工列表.xlsx"' # 返回生成的Excel内容
方案二:在视图中设置
如果你需要根据请求参数动态生成文件名,可以在视图的get方法中设置,修改后的视图代码如下:
# app/views.py class EmployeeAPIView(ListAPIView): serializer_class = EmployeeSerializer renderer_classes = [PDFRenderer, XLSXRenderer, JSONRenderer] def get_queryset(self): return Employee.objects.filter(created_by=self.request.user) def get(self, request, *args, **kwargs): # 原代码调用get_paginated_response是错误的,直接调用父类get方法即可拿到响应 response = super().get(request, *args, **kwargs) # 根据当前选中的渲染器设置对应文件名 if isinstance(request.accepted_renderer, PDFRenderer): filename = "员工列表.pdf" response['Content-Disposition'] = f'attachment; filename="{filename}"' elif isinstance(request.accepted_renderer, XLSXRenderer): filename = "员工列表.xlsx" response['Content-Disposition'] = f'attachment; filename="{filename}"' return response
补充说明
如果需要动态生成文件名,比如拼接当前日期、用户信息等,直接修改filename变量的取值即可,不需要改动其余逻辑。
内容的提问来源于stack exchange,提问作者abybaddi009
相关产品推荐
相关产品推荐

