Написание собственной системы хранения

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

  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.listdir().

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

В конечном итоге, какой из этих методов будет реализован, зависит от вас. Если оставить некоторые методы нереализованными, интерфейс будет частично (возможно, сломан).

Вы также обычно хотите использовать ловушки, специально разработанные для пользовательских объектов хранения. Эти:

_open( имя , режим = 'rb' )

Обязательно .

Вызывается Storage.open(), это фактический механизм, который класс хранилища использует для открытия файла. Это должно возвращать Fileобъект, хотя в большинстве случаев вы захотите вернуть здесь некоторый подкласс, который реализует логику, специфичную для внутренней системы хранения.

_save( имя , содержание )

Вызывается Storage.save(). nameУже прошли get_valid_name()и get_available_name(), и contentбудет Fileсам объект.

Должен возвращать фактическое имя имени сохраненного файла (обычно name передается, но если хранилище необходимо изменить имя файла, вместо этого верните новое имя).

get_valid_name( имя )

Возвращает имя файла, подходящее для использования с базовой системой хранения. nameАргумент , передаваемый этому методу либо исходное имя файла отправляется на сервер , или, если upload_toэто отозваны, имя файла , возвращаемое этим методом после того, как любая информация , путь удаляется. Переопределите это, чтобы настроить преобразование нестандартных символов в безопасные имена файлов.

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

get_alternative_name( корневой_файл , файл_внешний )

Возвращает альтернативное имя файла на основе file_rootи file_ext параметров. По умолчанию перед расширением к имени файла добавляется символ подчеркивания и случайная буквенно-цифровая строка из 7 символов.

get_available_name( name , max_length = None )

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

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

Если файл с nameуже существует, get_alternative_name()вызывается для получения альтернативного имени.

Copyright ©2021 All rights reserved