Django图片上传目录迁移报错:[WinError 3] 系统找不到指定路径
问题分析
报错的核心原因是路径拼接时重复添加了product_images层级。模型字段的upload_to已经指定基础路径为product_images,上传后的图片实际存储路径是基于MEDIA_ROOT的product_images/xxx.jpg;如果change_directory函数里再次以product_images/{file_name}作为目标路径,会生成MEDIA_ROOT/product_images/product_images/{file_name}这种不存在的路径,触发找不到路径的错误。
解决方案
1. 修正change_directory函数的路径逻辑
确保目标路径基于已上传图片的基础路径创建子目录,避免重复拼接product_images:
import os from django.conf import settings from shutil import move def change_directory(image_relative_path, target_subdir): # 拼接图片的完整本地路径 full_source_path = os.path.join(settings.MEDIA_ROOT, image_relative_path) filename = os.path.basename(full_source_path) # 构建目标子目录(基于MEDIA_ROOT/product_images) target_dir = os.path.join(settings.MEDIA_ROOT, 'product_images', target_subdir) # 递归创建目录,已存在则跳过 os.makedirs(target_dir, exist_ok=True) # 构建目标文件路径并移动文件 full_target_path = os.path.join(target_dir, filename) move(full_source_path, full_target_path) # 返回更新后的相对路径(用于同步模型字段) return os.path.join('product_images', target_subdir, filename)
2. 修正视图中的调用逻辑
在form_valid中调用工具函数时,传入图片的相对路径,并更新模型实例的图片字段:
from django.views.generic.edit import CreateView from .models import Product from .utils import change_directory class ProductCreateView(CreateView): model = Product form_class = ProductForm success_url = '/products/' def form_valid(self, form): self.object = form.save() # 假设模型中图片字段为image1至image5 image_fields = ['image1', 'image2', 'image3', 'image4', 'image5'] # 自定义子目录名,示例用产品名称(可根据需求调整) target_subdir = self.object.name.replace(' ', '_') for field_name in image_fields: image_field = getattr(self.object, field_name) if image_field: # 更新图片路径并同步到模型 new_image_path = change_directory(image_field.name, target_subdir) setattr(self.object, field_name, new_image_path) self.object.save() return super().form_valid(form)
3. 验证路径流程
- 上传时图片先存入
MEDIA_ROOT/product_images/xxx.jpg - 迁移后移动到
MEDIA_ROOT/product_images/{target_subdir}/xxx.jpg - 模型中存储的相对路径同步更新为
product_images/{target_subdir}/xxx.jpg,彻底避免路径重复
注意事项
- 确保
MEDIA_ROOT配置正确,且该目录有读写权限 - 移动文件后必须更新模型字段的路径,否则后续读取图片会失败
- 若子目录名包含特殊字符,需提前做转义处理,避免路径非法
内容的提问来源于stack exchange,提问作者Emerica11
相关产品推荐
相关产品推荐

