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

Django+DRF大文件上传场景下如何获取上传进度

可行实现方案

下面是4种适配不同需求的实现方式,按改造成本从低到高排序:

1. 前端XHR原生进度监听(零后端改造,最省事)

这个方案完全不需要修改你现有的后端上传逻辑,只需要调整前端上传代码即可:

  • 前端放弃默认表单提交,改用XMLHttpRequest或者fetch发起上传请求
  • 监听XHR的upload.onprogress事件,直接从回调参数中拿到event.loaded(已传输到服务器的字节数)和event.total(文件总字节数),计算百分比渲染进度条即可

注意:这个方案统计的是文件传输到服务器的进度,不是服务器写入磁盘/存储的进度。如果你的文件上传后还有转存、校验等后置处理,该进度会比实际业务完成进度快,仅适合只需要统计传输进度的场景。

2. 轮询查询接口(实现最简单,兼容性最好)

需要少量后端改造,稳定性最高:

  • 新增一个预申请接口:前端发起上传前先请求该接口,获取唯一的上传任务ID,后续上传请求携带该ID
  • 修改你现有的分片写入逻辑:每写完一个chunk,就把「已写入字节数、文件总大小」存入缓存(Redis/Django自带缓存框架都可),缓存key用任务ID,同时设置合理的过期时间
  • 新增进度查询接口:接收任务ID作为参数,从缓存读取进度数据计算百分比返回给前端
  • 前端上传过程中每隔1-3秒主动调用一次查询接口,更新进度条即可

注意:上传完成/失败后要主动删除对应缓存,避免无用数据占用存储。

3. SSE服务器推送(比轮询省资源,实时性更高)

适合不想用轮询、只需要后端单向推送进度的场景:

  • 前端上传前先和后端建立SSE长连接,携带对应上传任务ID
  • 你现有分片写入逻辑中,每写完一个chunk就通过SSE连接把最新进度推送给前端
  • 上传完成后后端主动断开SSE连接即可

注意:Django默认的同步WSGI服务不适合处理长连接,建议切换为ASGI协议(搭配Uvicorn等ASGI服务器)使用,避免长连接占满worker导致其他请求无法处理。

4. Websocket通信(扩展性最强)

如果后续还要实现断点续传、暂停上传等复杂交互,推荐用这个方案:

  • 前端上传前先和后端建立Websocket连接,绑定对应上传任务ID
  • 分片写入时通过Websocket主动推送进度到前端,无需前端主动拉取
  • 可以直接扩展支持暂停、取消、断点续传等指令交互

注意:Django需要搭配Channels组件实现Websocket支持,同样推荐使用ASGI协议部署。

现有代码优化建议

针对你当前的上传代码,可以做两个调整适配大文件场景:

  • 调整Django配置:把FILE_UPLOAD_MAX_MEMORY_SIZE和DATA_UPLOAD_MAX_MEMORY_SIZE调整到你需要的阈值,避免大文件请求被默认规则拦截
  • 调整分片大小:你当前的chunk_size设置为1MB,2GB文件需要循环2000次IO,建议调整为5MB~10MB,减少磁盘IO次数提升写入效率

内容的提问来源于stack exchange,提问作者Santhosh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 07:57:04