Spec-Zone.ru › Django 5.0

Как написать класс пользовательского хранилища

Если вам нужно предоставить пользовательское хранилище файлов — распространённым примером является хранение файлов на какой-либо удалённой системе — вы можете сделать это, определив класс пользовательского хранилища. Вам нужно выполнить следующие шаги:

  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.delete()
  • Storage.exists()
  • Storage.listdir()
  • Storage.size()
  • Storage.url()

Однако не все эти методы обязательны и могут быть намеренно пропущены. Возможно, каждый метод можно оставить нереализованным, и хранилище всё равно будет работать.

Например, если создание списка содержимого определённых хранилищ оказывается дорогостоящим, вы можете решить не реализовывать 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_root и file_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"]

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.0/howto/custom-file-storage/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API