如何编写自定义存储类

如果你需要提供自定义文件存储(一个常见的示例是在某些远程系统上存储文件),你可以通过定义一个自定义存储类来实现。你需要遵循以下步骤

  1. 你的自定义存储系统必须是 django.core.files.storage.Storage 的子类

    from django.core.files.storage import Storage
    
    
    class MyStorage(Storage): ...
    
  2. Django 必须能够在没有任何参数的情况下实例化你的存储系统。这意味着任何设置都应从 django.conf.settings 中获取

    from django.conf import settings
    from django.core.files.storage import Storage
    
    
    class MyStorage(Storage):
        def __init__(self, option=None):
            if not option:
                option = settings.CUSTOM_STORAGE_OPTIONS
            ...
    
  3. 你的存储类必须实现 _open()_save() 方法,以及任何其他适用于你的存储类的其他方法。请参阅以下内容以了解有关这些方法的更多信息。

    此外,如果你的类提供本地文件存储,则它必须覆盖 path() 方法。

  4. 您的存储类必须是 可解构的,以便在迁移中的字段上使用时可以序列化。只要您的字段具有本身 可序列化的 参数,您就可以为此使用 django.utils.deconstruct.deconstructible 类装饰器(这是 Django 在 FileSystemStorage 上使用的)。

默认情况下,以下方法会引发 NotImplementedError,并且通常需要覆盖

但请注意,并非所有这些方法都是必需的,并且可以故意省略。事实上,可以将每个方法保留为未实现,并且仍然具有可工作的存储。

例如,如果列出某些存储后端的目录内容变得昂贵,您可能决定不实现 Storage.listdir()

另一个示例是仅处理写入文件的后端。在这种情况下,您不需要实现上述任何方法。

最终,实现哪些方法取决于您。保留某些方法未实现将导致部分(可能已损坏)接口。

您通常还希望使用专门为自定义存储对象设计的钩子。这些是

_open(name, mode='rb')

必需.

Storage.open() 调用,这是存储类用于打开文件的确切机制。这必须返回一个 File 对象,但在大多数情况下,您需要在此处返回实现特定于后端存储系统的逻辑的某个子类。当文件不存在时,应引发 FileNotFoundError 异常。

_save(name, content)

Storage.save() 调用。 name 已经通过 get_valid_name()get_available_name(),而 content 本身将是一个 File 对象。

应返回保存的文件的实际名称(通常是传入的 name,但如果存储需要更改文件名,则返回新名称)。

get_valid_name(name)

返回适合与底层存储系统一起使用的文件名。传递给此方法的 name 参数要么是发送到服务器的原始文件名,要么(如果 upload_to 是一个可调用对象)是删除任何路径信息后由该方法返回的文件名。覆盖此方法以自定义如何将非标准字符转换为安全文件名。

Storage 上提供的代码仅保留原始文件名中的字母数字字符、句点和下划线,并删除其他所有内容。

get_alternative_name(file_root, file_ext)

基于 file_rootfile_ext 参数返回一个备用文件名。默认情况下,在扩展名前面附加一个下划线和一个随机的 7 个字符的字母数字字符串。

get_available_name(name, max_length=None)

返回存储机制中可用的文件名,可能考虑提供的文件名。传递给此方法的 name 参数将根据上面描述的 get_valid_name() 方法清除为对存储系统有效的文件名。

如果提供了,文件名长度将不超过 max_length。如果找不到空闲的唯一文件名,则会引发 SuspiciousFileOperation 异常。

如果已经存在具有 name 的文件,则调用 get_alternative_name() 以获取备用名称。

使用您的自定义存储引擎

Django 4.2 中的新增功能。

使用 Django 的自定义存储的第一步是告知 Django 您将使用的文件存储后端。这是使用 STORAGES 设置完成的。此设置映射存储别名(一种在整个 Django 中引用特定存储的方式)到特定存储后端的设置字典。内部字典中的设置在 STORAGES 文档中进行了全面描述。

然后通过别名从 django.core.files.storage.storages 字典访问存储

from django.core.files.storage import storages

example_storage = storages["example"]
返回顶部