Spec-Zone.ru › Django 4.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, хотя в большинстве случаев вы захотите вернуть здесь какой-либо подкласс, реализующий логику, специфичную для системы хранения бэкенда.

_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 Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/4.0/howto/custom-file-storage/

Spec-Zone.ru

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