使用django-storages的SFTPStorage上传文件触发RecursionError如何修复?
错误原因说明
- 核心是依赖版本不兼容:你当前使用的
paramiko==2.7.2版本发布时适配的是更早版本的cryptography,和cryptography==3.4.7的ECDSA密钥解析逻辑存在冲突,解析本地known_hosts文件里的ECDSA格式主机密钥时触发了递归死循环。 - 配置层面的触发因素:django-storages的SFTPStorage默认会自动加载本地用户目录下的
~/.ssh/known_hosts文件做主机密钥校验,你的环境里这个文件包含对应192.168.1.103服务器的ECDSA格式密钥条目,刚好触发了上述版本兼容bug。
修复方案
方案1:升级依赖(推荐)
直接升级paramiko到兼容高版本cryptography的版本即可解决底层递归bug:
pip install paramiko==2.10.1
这个版本及以上的paramiko已经修复了和cryptography 3.4+版本的ECDSA密钥解析兼容问题,不需要修改任何业务代码和配置。
方案2:调整SFTP配置跳过主机密钥校验(适合内网安全环境,不想改依赖版本的场景)
你的场景是无互联网的本地局域网,不需要严格做主机密钥校验,可以在settings.py的SFTP_STORAGE_PARAMS里添加参数关闭主机密钥加载,直接绕过触发bug的逻辑:
首先在settings.py头部导入依赖:
import paramiko
再修改存储参数配置:
SFTP_STORAGE_PARAMS = { "username": "[远端服务器用户名]", "password": "[远端服务器密码]", "look_for_keys": False, "allow_agent": False, "host_key_policy": paramiko.client.AutoAddPolicy() }
这个方案会让SSH客户端自动接受陌生主机的密钥,不需要读取本地known_hosts文件,直接跳过触发错误的代码路径。
方案3:优化模型字段的冗余配置
你已经在settings.py里配置了全局DEFAULT_FILE_STORAGE为SFTPStorage,不需要再在ImageField里重复指定storage参数,多余的实例化可能会导致连接重复初始化,建议修改模型字段为:
image = models.ImageField(null=True)
如果是部分字段需要单独用SFTP存储、其他字段用默认存储的场景,也要确保SFTPStorage实例是单例,不要每次模型加载都重复初始化。
内容的提问来源于stack exchange,提问作者Anne Haley
相关产品推荐
相关产品推荐

