Spec-Zone.ru › Django 5.2

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

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

  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. Ваш класс хранения должен быть deconstructible, чтобы его можно было сериализовать при использовании в поле миграции. Пока ваше поле имеет аргументы, которые сами по себе serializable, вы можете использовать декоратор класса 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 — сообщить 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.2/howto/custom-file-storage/

Spec-Zone.ru

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