我编写了一个自定义渲染器,允许将嵌套的 json 数据渲染为平面 Excel 文件。
class ExcelRenderer(renderers.BaseRenderer):
"""Custom renderer for exporting XLS files"""
media_type = "application/xlsx"
format = "excel"
render_style = 'binary'
def render(self, data, accepted_media_type=None, renderer_context=None):
query_params = renderer_context["request"].query_params
query_params = "_".join([f"{v.split('T')[0]}" for k,v in query_params.items()])
"""
Render `data` into XLSX workbook, returning a workbook.
"""
try:
df = json_into_flat_dataframe(data)
except Exception as e:
logger.error(e, exc_info=True)
df = pd.DataFrame()
if len(df.index) == 0:
raise rest_exceptions.APIException("No data!")
output = io.BytesIO()
# Use a temp filename to keep pandas happy.
writer = pd.ExcelWriter(output, engine='xlsxwriter')
# Write the data frame to the StringIO object.
df.to_excel(writer, sheet_name='Sheet1', index=False)
writer.save()
data = output.getvalue()
#Enable direct download.
renderer_context['response']["content-disposition"] = f"attachment; filename=vodepro_export_{query_params}.xlsx"
return data
只要在渲染之前的过程中没有异常(例如
ValidationError
),这就会按预期工作。当出现 ValidationError 时,我的自定义渲染器会尝试渲染它(但失败了,因为这甚至不是渲染器的设计行为)。
我想实现一个渲染器,它不会尝试将 ValidationErrors(或任何其他异常)解析为 Excel,但在这种情况下会回退到正常的 DRF 行为(json 或 BrowsableAPI 渲染器)?
这里是代码的完整答案:
from rest_framework.renderers import JSONRenderer
from rest_framework.views import exception_handler
def custom_exception_handler(exc, context):
""" Switch from PDFRenderer to JSONRenderer for exceptions """
if context['request'].accepted_renderer.format == 'pdf':
context['request'].accepted_renderer = JSONRenderer()
return exception_handler(exc, context)
如果您已有自定义异常处理程序,请将其替换为上面代码段中 rest_framework.views 中的默认处理程序。
然后您需要在设置中进行设置:
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}
你可以参考这个答案。