Django POST请求返回文件报错File object is not JSON serializable如何解决
Django POST请求返回文件解决方案
报错根因
- 原代码直接将序列化器实例传入
Response,未调用.data属性获取可被JSON序列化的结果 - 若需要直接返回文件流,DRF默认的
Response采用JSON序列化逻辑,无法处理文件对象
方案一:直接返回文件流触发下载
适合需要请求后直接触发浏览器/客户端下载的场景,使用Django原生FileResponse实现:
前置导入
from django.http import FileResponse
调整后完整代码
@api_view(['GET', 'POST']) def Upload_list(request): if request.method == 'GET': queryset = Uploads.objects.all() uploads=queryset.filter(owner=request.user) serializer = UploadSerializer(uploads, many=True) return Response(serializer.data) elif request.method == 'POST': serializer = UploadSerializer(data=request.data) if serializer.is_valid(): serializer.save(owner=request.user) # 取最新上传的文件对象 latest_file = File.objects.latest('created_at') # 替换file_field为你File模型中实际存储文件的字段名 file_handle = latest_file.file_field.open('rb') # 构造文件响应,as_attachment=True强制触发下载 response = FileResponse( file_handle, as_attachment=True, filename=latest_file.file_field.name ) # 可根据实际文件类型调整Content-Type,通用二进制类型为application/octet-stream response['Content-Type'] = 'application/octet-stream' return response return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
方案二:返回文件信息JSON(含访问地址)
适合前后端分离场景,仅需返回文件访问URL给前端自行处理预览/下载:
调整后POST逻辑代码
elif request.method == 'POST': serializer = UploadSerializer(data=request.data) if serializer.is_valid(): serializer.save(owner=request.user) # 修正原代码filter条件的错误,补取最新文件的id字段 respFile = File.objects.filter(id=File.objects.latest('created_at').id) serializers = Fileserializers(respFile, read_only=True, many=True) # 新增.data获取序列化后的可序列化数据 return Response(serializers.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
注意事项
- 大文件下载场景建议使用
StreamingHttpResponse替代FileResponse,避免内存溢出 - 若使用方案二,需提前配置Django媒体资源访问规则,序列化器会自动生成可直接访问的文件URL
内容的提问来源于stack exchange,提问作者Rihab sabri
相关产品推荐
相关产品推荐

