如何在Django测试中使用外部文件 解决SuspiciousFileOperation报错
问题根因
触发SuspiciousFileOperation的核心原因有三个,和你的SVG校验逻辑本身无关:
- 你定义的
DIR_PATH = "/tests/LinkSVG/"是操作系统根目录下的绝对路径,不是项目相对路径。Django自带的文件访问安全校验会直接拦截访问项目配置允许范围外的路径,你代码实际在找系统盘根目录下的tests文件夹,根本没读到项目内的测试文件。 - 测试用资源不应该依赖
django.contrib.staticfiles.finders.find读取:静态文件查找逻辑依赖全局静态文件配置,测试环境下默认不会把测试资源目录纳入静态文件扫描范围,即使路径写对也可能返回None,后续open的时候直接触发异常。 - 你给
File对象传参时写的name=file.name取到的是本地文件系统的绝对路径,FileField保存文件时会校验文件名的路径合法性,包含绝对路径的文件名会直接触发可疑文件操作拦截。
修复步骤
调整测试资源存放位置
在你当前app的tests目录下新建LinkSVG文件夹,把测试用的triangle.svg放到这个文件夹里,和测试代码文件保持同级目录结构,不要把测试资源放到static目录下。重写测试代码,用相对路径读取文件
不要写死绝对路径,也不要依赖静态文件查找器,基于当前测试文件的位置拼接测试资源的路径,同时修改File对象的传参,删掉没用的冗余导入:
from os import path from django.test import TestCase from django.core.files import File from .models import Link class LinkSVGTestCase(TestCase): def test_svg_file(self) -> None: # 基于当前测试文件的绝对路径,拼接测试SVG的路径 current_test_dir = path.dirname(path.abspath(__file__)) svg_path = path.join(current_test_dir, "LinkSVG", "triangle.svg") # 用二进制模式打开文件,避免编码问题 with open(svg_path, "rb") as f: Link.objects.create( name="Triangle", url="https://example.com/", # 文件名只传文件本身的名字,不要传本地绝对路径 icon=File(f, name="triangle.svg") )
额外说明
- 读文件必须用
rb二进制模式:SVG本质是XML格式文本,但Django文件存储默认按二进制流处理文件,用文本模式打开容易出现编码错误,影响后续SVG校验逻辑的运行。 - 如果你确实需要把测试SVG放在static目录下,需要在测试配置里把测试资源所在的static目录加入
STATICFILES_DIRS,同时路径不要以/开头,否则还是会被判定为非法绝对路径。但这种方案依赖静态文件配置,稳定性远低于直接基于测试文件位置拼路径的方案。
内容的提问来源于stack exchange,提问作者volkovik
相关产品推荐
相关产品推荐

