Spec-Zone.ru › Django 2.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_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.0/howto/custom-file-storage/

Spec-Zone.ru

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