You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 10:15:08