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

Django 3.2.8部署环境(debug=false)触发SuspiciousFileOperation路径遍历异常

问题根因

  1. Django FileField的upload_to回调要求返回相对storage根目录的路径,你当前的get_folder方法返回的是从settings.TEMPLATES_FOLDER开头的绝对路径,生产模式下(debug=False)Django会开启严格的路径安全校验,判定该路径存在遍历风险。
  2. Django 3.2.8版本对Path类型的返回值存在校验逻辑缺陷,拼接后的绝对路径无法正确通过根目录归属校验,debug模式下该校验不会触发,因此开发环境运行正常。
  3. post_save信号未触发是因为路径校验异常抛出在模型写入数据库之前。

解决方案

方案1:修改upload_to返回相对路径(最简便)

直接修改get_folder方法,返回相对于MEDIA_ROOT的相对路径即可:

def get_folder(self, filename):
    filename_PATH = Path(filename)
    template_dir = filename_PATH.stem
    # 返回相对路径:TEMPLATES/文件名前缀/原文件名
    return str(Path("TEMPLATES") / template_dir / filename)

方案2:自定义存储指定根目录

如果你需要保留存储类的独立性,可直接给OverwriteStorage指定根目录为TEMPLATES_FOLDER,此时upload_to只需要返回两级相对路径即可:

# models.py
class OverwriteStorage(FileSystemStorage):
    def __init__(self, *args, **kwargs):
        kwargs["location"] = settings.TEMPLATES_FOLDER
        super().__init__(*args, **kwargs)
    
    def get_available_name(self, name, max_length=None):
        self.delete(name)
        return name

class Template(models.Model):
    def get_folder(self, filename):
        filename_PATH = Path(filename)
        template_dir = filename_PATH.stem
        return str(Path(template_dir) / filename)

    # 其他字段保持不变
    name = models.CharField("template", max_length=32, unique=True)
    file = models.FileField("templatefile", upload_to=get_folder, null=True, max_length=260, storage=OverwriteStorage())

两种方案任选其一即可解决生产环境的路径校验异常问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:45:07