如何在不使用模型的情况下修改Django InMemoryUploadedFile文件名后上传至S3
运行环境
- Django==3.24
- DRF==3.11
- boto3==1.16
- django-storages==1.10
问题原因
os.rename()是操作本地磁盘实体文件的方法,而你从请求中拿到的InMemoryUploadedFile类型文件是临时存放在内存中,并没有写入本地磁盘,磁盘上不存在对应源文件,因此调用该方法会抛出FileNotFoundError。
解决方案
你不需要调用系统命令修改文件名,有两种简单的实现方式:
方法1:直接使用新生成的文件名拼接存储路径(最省事)
直接把你生成的随机文件名作为路径的一部分传给存储后端即可,不需要修改原文件对象的属性,修改后代码如下:
# in Post request import random import string import os files = request.FILES.getlist('files') res = [] # file_directory_within_bucket 替换为你实际的桶内目录前缀 for file in files: random_str = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(8)) ext = file.name.split('.')[-1] file_name = f'{random_str}.{ext}' # 直接用新生成的文件名拼桶内路径 file_path_within_bucket = os.path.join( file_directory_within_bucket, file_name ) default_storage.save(file_path_within_bucket, file) file_url = default_storage.url(file_path_within_bucket) res.append(file_url)
方法2:直接修改InMemoryUploadedFile的name属性
如果你确实需要修改文件对象本身的名称,直接给file.name赋值即可:
# 生成新文件名的逻辑不变 file.name = file_name # 后续路径拼接依然可以用file.name file_path_within_bucket = os.path.join( file_directory_within_bucket, file.name )
内容的提问来源于stack exchange,提问作者Miguel
相关产品推荐
相关产品推荐

