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

Django+AWS S3分片上传报错:No such file or directory

问题描述

尝试了所有方法都没用,大概知道问题出在哪但不知道怎么修复。用分片上传方案绕过Cloudflare的100MB文件上传限制,执行代码时出现文件找不到的错误,目前只需要把视频保存到AWS S3,图片逻辑类似。

报错信息

with open(object_name, 'rb') as destination:
FileNotFoundError: [Errno 2] No such file or directory: '/home/mrlonely/Desktop/lumen/lumen/Bones - TheArtOfCremation-tqSpI1Jm0YE-1080p.mp4'

相关代码(create_post视图函数)
def create_post(request):
    # s3_client=boto3.client('s3')
    s3 = boto3.client('s3', region_name=settings.AWS_S3_REGION_NAME, aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
                          aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY)
    categories_1 = Category.objects.all()
    if request.method == 'POST':   
        file = request.FILES['file'].read()
        file_name_s3 = request.POST['filename']
        fileName= request.POST['filename'].replace(' ', '')
        fileName_STR = re.sub("[^A-Z]", "", fileName,0,re.IGNORECASE) + '.mp4'
        existingPath = request.POST['existingPath']
        end = request.POST['end']
        image = request.FILES.get('image', False)
        imageName = request.FILES.get('imagename', False)

        if image != False:
                image = request.FILES['image'].read()
                imageName= request.POST['imagename'].replace(' ', '')
        else:
                pass
        title = request.POST['title']
        tags = request.POST['tags']
        categories = parse_ids(request.POST['categories'])
        description = request.POST['description']
        nextSlice = request.POST['nextSlice']


        if file=="" or fileName_STR=="" or existingPath=="" or end=="" or nextSlice=="":
            res = JsonResponse({'data':'Invalid Request'})
            return res
        else:
            if existingPath == 'null':
                path = 'media/uploads/video_files/' + fileName
                
                if image != False: 
                    with open(path, 'wb+') as destination: 
                        destination.write(file)
                    imagePath = 'media/thumbnail/' + imageName
                else:
                    pass
                if image:
                    with open(imagePath, 'wb+') as destination:
                        destination.write(image)
                else: 
                    pass
                
                
                object_name = Path.joinpath(BASE_DIR, file_name_s3)
                # handles the upload...................
                path = 'media/uploads/video_files/' + fileName_STR
                with open(object_name, 'rb') as destination:
                    s3_client.upload_file(object_name ,bucket,fileName_STR)
                # ............................................
                FileFolder = Post()
                FileFolder.video = 'uploads/video_files/'+fileName_STR
                FileFolder.existingPath = fileName_STR
                FileFolder.eof = end
                FileFolder.title = title
                FileFolder.author = request.user
                FileFolder.description = description

                if image == False:
                    FileFolder.thumbnail = None
                else:
                    FileFolder.thumbnail = 'thumbnail/' + imageName

                FileFolder.approved = True
                FileFolder.save()
                tag_list = taggit.utils._parse_tags(tags)
                FileFolder.tags.add(*tag_list)
                categories_post = Category.objects.filter(id__in=categories)
                if categories_post:
                    for category in categories_post:
                        FileFolder.categories.add(category)
                if int(end):
                    res = JsonResponse({'data':'Uploaded Successfully','existingPath': fileName})
                else:
                    res = JsonResponse({'existingPath': fileName_STR})
                return res
            else:
                path = 'media/uploads/video_files/' + existingPath
                model_id = Post.objects.get(existingPath=existingPath)
                if model_id.title == title:
                    if not model_id.eof:
                        with open(path, 'ab+') as destination: 
                            destination.write(file)
                        if int(end):
                            model_id.eof = int(end)
                            model_id.save()
                            res = JsonResponse({'data':'Uploaded Successfully','existingPath':model_id.existingPath})
                        else:
                            res = JsonResponse({'existingPath':model_id.existingPath})    
                        return res
                    else:
                        res = JsonResponse({'data':'EOF found. Invalid request'})
                        return res
                else:
                    res = JsonResponse({'data':'No such file exists in the existingPath'})
                    return res
    return render(request, 'main/create_post.html', {'categories': categories_1})
问题根源与修复方案

1. 错误核心

代码中文件写入路径和读取路径不匹配:

  • 分片内容被写入到media/uploads/video_files/下的文件
  • 上传S3时却尝试读取BASE_DIR根目录下的file_name_s3文件,这个文件根本不存在,自然报找不到的错误
  • 另外代码里初始化了s3客户端,但上传时用了未定义的s3_client,变量名也不一致

2. 修复步骤

(1)统一文件路径

把分片写入和S3读取的路径统一,确保操作的是同一个文件:

# 替换existingPath == 'null'分支里的路径相关代码
if existingPath == 'null':
    # 定义统一的本地视频存储路径
    local_video_dir = Path.joinpath(BASE_DIR, 'media', 'uploads', 'video_files')
    # 确保目录存在,避免因目录缺失报错
    local_video_dir.mkdir(parents=True, exist_ok=True)
    local_video_path = local_video_dir / fileName_STR
    
    # 写入当前分片内容
    with open(local_video_path, 'wb+') as destination:
        destination.write(file)
    
    # 图片处理逻辑(略,同样要确保目录存在)
    if image:
        local_image_dir = Path.joinpath(BASE_DIR, 'media', 'thumbnail')
        local_image_dir.mkdir(parents=True, exist_ok=True)
        local_image_path = local_image_dir / imageName
        with open(local_image_path, 'wb+') as destination:
            destination.write(image)

(2)修正S3上传逻辑

只有当所有分片上传完成(end为1)时,才上传到S3,同时使用正确的客户端和路径:

# 补充bucket变量(需要从配置中获取)
bucket = settings.AWS_STORAGE_BUCKET_NAME

# 在end为1时执行S3上传
if int(end):
    # 使用已初始化的s3客户端,传入正确的本地文件路径
    s3.upload_file(str(local_video_path), bucket, fileName_STR)

(3)其他细节修正

  • 变量名统一:避免fileName和fileName_STR混用,减少混淆
  • Post模型创建时机:不要在每个分片请求都创建模型,应该在第一个分片时创建,后续分片更新模型状态
  • 临时文件清理:上传完成到S3后,可以删除本地临时文件,节省存储空间

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 03:21:05