移动文件而不在 django-storages 和 S3 中打开

Pet*_*ott 3 python django amazon-s3

我使用 django 与 django-storages 和 S3 来管理一些上传的文件。这些文件可以上传到“feature”文件夹中,例如:

/uploads/products/ 产品代码/功能/文件名.pdf

我想将文件移出此功能文件夹,删除原始文件(最终删除所有文件后的包含文件夹),以便可以在以下位置找到它们:

/上传/产品/产品代码/文件名.pdf

我目前有以下代码来执行此操作:

def move_files_in_folders(path, folder):
    files = default_storage.listdir(path+"/"+folder)
    returnable_file_list = list()

    for filename in files[1]:
        if filename is not '':

            movable_file = default_storage.open(path+'/'+folder+'/'+filename)
            default_storage.save(path+'/'+filename, movable_file)
            default_storage.delete(path+'/'+folder+'/'+filename)
            returnable_file_list.append(filename)

    default_storage.delete(path + '/' + folder)
    return returnable_file_list
Run Code Online (Sandbox Code Playgroud)

这可行,但对于长文件列表来说非常慢,因为系统必须打开每个文件并重新保存它。

有没有办法重构此代码以避免昂贵的打开和保存调用?

fra*_*ram 5

您可以对 S3Boto3Storage 类进行子类化,并添加一个将文件从 from_path 复制到 to_path 的方法

from storages.backends.s3boto3 import S3Boto3Storage

class MyS3Storage(S3Boto3Storage):
    def copy(self, from_path, to_path):
        from_path = self._normalize_name(self._clean_name(from_path))
        to_path = self._normalize_name(self._clean_name(to_path))

        copy_result = self.connection.meta.client.copy_object(
            Bucket=self.bucket_name,
            CopySource=self.bucket_name + "/" + from_path,
            Key=to_path)

        if copy_result['ResponseMetadata']['HTTPStatusCode'] == 200:
            True
        else:
            False
Run Code Online (Sandbox Code Playgroud)

之后,您可以创建 MyS3Storage 对象并使用 from 和 to 路径调用复制文件。