Spec-Zone.ru › Django 4.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. Ваш класс хранения должен быть деконструируемым, чтобы его можно было сериализовать при использовании в поле в миграции. Пока ваше поле имеет аргументы, которые сами по себе сериализуемы, вы можете использовать декоратор класса 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 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/4.2/howto/custom-file-storage/

Spec-Zone.ru

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