Django分片上传需避免内存加载,用request.FILES.get('file')接收单片,配合identifier、chunkIndex等元数据校验;分片独立存储并原子覆盖,合并前检查完整性并加锁;提供check接口支持断点续传,强制超时清理与路径防护。

如何用 Django 接收前端传来的文件分片
核心是别把整个文件当 request.FILES 一次性读进内存。Django 默认会把小文件加载到内存,大文件写入临时文件,但分片上传时你收到的只是某个 chunk,不是完整文件,所以必须手动处理原始 body 或指定字段名接收。
常见做法是前端按约定字段(如 file)上传单个分片,后端用 request.FILES.get('file') 拿到 InMemoryUploadedFile 或 TemporaryUploadedFile。但要注意:
- 确保 Nginx / uWSGI 配置不限制单次请求体大小(如 Nginx 的
client_max_body_size至少设为 100m) - 禁用 Django 的文件上传中间件自动解析(不必要),直接从
request.FILES取值即可 - 分片通常带元数据:当前序号
chunkIndex、总片数totalChunks、文件唯一标识identifier,这些走request.POST,别混在文件字段里
怎样安全合并分片并避免重复写盘
不能等所有分片收齐再合并——万一用户中途关浏览器,磁盘上就堆了一堆孤儿 chunk。更稳妥的做法是每个分片落地为独立临时文件(带 identifier 和 chunkIndex 命名),合并逻辑只在「确认上传完成」时触发。
关键控制点:
立即学习“Python免费学习笔记(深入)”;
- 用
os.path.join(upload_dir, f"{identifier}_{chunkIndex}")存每片,目录需提前创建且权限可控 - 合并前先检查是否收齐:
len(os.listdir(chunk_dir)) == int(totalChunks),但注意竞态——多个请求可能同时检查+合并,加文件锁或数据库状态位(如UploadSession.status == 'completed') - 合并时用
open(..., 'ab')追加写入目标文件,不要用read()全部载入内存;用shutil.copyfileobj(chunk_file, target_file)流式拷贝
断点续传依赖哪些客户端行为和后端校验
断点续传不是后端单方面能实现的,它依赖前端准确汇报「已传哪些片」。后端只需提供一个查询接口(如 /api/upload/check/?identifier=xxx),返回已存的 chunkIndex 列表即可。
但容易被忽略的是校验环节:
- 仅靠
identifier不足以防冲突,建议用文件名 + 文件大小 + 时间戳生成强标识,或直接用文件内容 hash(首尾各 1MB 的sha256拼接) - 前端重传同一片时,后端要覆盖写,而非追加——否则文件错乱;可用
os.replace()确保原子性 - 超时清理必须做:对超过 24 小时未完成的
identifier,后台任务扫描并删其所有 chunk,否则磁盘悄悄爆掉
Django 视图中怎么组织分片上传逻辑才不易出错
别在一个视图里塞接收、校验、合并、清理全部逻辑。拆成三个最小职责单元:
-
upload_chunk视图:只存单片,校验identifier和chunkIndex合法性,返回 200 或 400 -
check_chunks视图:只查已传片列表,不做任何写操作,供前端决定从哪片继续 -
merge_chunks视图:只在收到totalChunks且全部存在时执行合并,并标记 session 完成;失败则留日志,不静默吞异常
合并失败时,不要删已存分片——保留它们能让用户下次直接续传,而不是重头开始。
最麻烦的其实是 chunk 文件名编码和路径遍历防护。哪怕用了 identifier,也要用 os.path.basename(identifier) 过滤掉 ../ 类路径穿越,否则攻击者能往任意目录写分片。


















