Spec-Zone.ru › Django 2.1

Создание пользовательской системы хранения

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

  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_available_name(name, max_length=None)

Возвращает имя файла, доступное в механизме хранения, возможно, с учётом предоставленного имени файла. Аргумент name передаваемый этому методу уже очищен до имени файла, допустимого для системы хранения, согласно методу get_valid_name() описанному выше.

Длина имени файла не будет превышать max_length, если это задано. Если уникальный свободный файл не найден, возбуждается исключение SuspiciousFileOperation.

Если файл с name уже существует, к имени файла перед расширением добавляется подчёркивание и случайная 7-символьная буквенно-цифровая строка.

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

Spec-Zone.ru

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