Spec-Zone.ru › Django 1.9

Создание собственной системы хранения

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

  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 является вызываемым объектом, именем файла, возвращённым этим методом после удаления любой информации о пути. Переопределите этот метод, чтобы настроить преобразование нестандартных символов в безопасные имена файлов.

В более ранних версиях этот метод не вызывался, когда upload_to был вызываемым объектом.

В приведённом на Storage коде сохраняются только буквенно-цифровые символы, точки и нижние подчёркивания из исходного имени файла, удаляя всё остальное.

get_available_name(name, max_length=None)

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

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

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

Аргумент max_length был добавлен.

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

Spec-Zone.ru

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