Django视图保存模型File正常,Celery任务仅存实例不存文件如何解决
问题原因及解决方案
核心原因(90%概率可解决你的问题)
你在调用write_pdf写入BytesIO对象后,文件指针停在了内容末尾,直接传入File对象时读取不到任何内容,导致存储后端跳过了文件写入操作,但模型层仍会正常生成存储路径、保存实例,完全匹配你遇到的现象。
修复步骤
1. 调整BytesIO指针位置
在Celery任务的write_pdf执行后新增指针重置代码:
HTML(string=html).write_pdf(out, stylesheets=[ CSS(settings.STATIC_ROOT + "/css/pdf.css"), 'https://fonts.googleapis.com/css2?family=Montserrat&family=Playfair+Display&display=swap' ]) out.seek(0) # 新增这行,将文件指针移到内容开头
2. 排查Celery运行环境差异
如果调整指针后仍未解决,按以下方向核对:
- 确认Celery worker启动时加载的Django配置与Web服务完全一致,重点核对
MEDIA_ROOT、DEFAULT_FILE_STORAGE两个配置项 - 确认运行Celery worker的系统用户对
MEDIA_ROOT目录具备读写权限 - 若使用第三方云存储(如OSS、S3),确认Celery运行环境有对应的访问密钥、网络访问权限
3. 补充日志定位隐藏问题
将现有异常捕获逻辑调整为输出完整异常栈,同时验证文件生成是否正常:
try: document.save() logger.info(f"文件大小:{document.file.size}") # 若输出为0则仍为内容读取问题 except Exception as e: logger.exception(e) # 输出完整异常栈,避免遗漏底层错误
4. 检查自定义逻辑兼容性
如果项目中有自定义FileField存储逻辑、模型保存信号,确认相关逻辑没有依赖Web请求上下文,导致Celery异步场景下跳过了文件写入流程。
内容的提问来源于stack exchange,提问作者R. Steigmeier
相关产品推荐
相关产品推荐

