Spec-Zone.ru › Django 1.10

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

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

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

Изменено в Django 1.9:

В более ранних версиях этот метод не вызывался, когда 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/1.10/howto/custom-file-storage/

Spec-Zone.ru

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