Создание пользовательской системы хранения
Если вам нужно предоставить пользовательское хранилище файлов — распространённый пример — хранение файлов на какой-либо удалённой системе — вы можете сделать это, определив пользовательский класс хранилища. Вам нужно выполнить эти шаги:
-
Ваша пользовательская система хранения должна быть подклассом
django.core.files.storage.Storage:from django.core.files.storage import Storage class MyStorage(Storage): ... -
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 ... -
Ваш класс хранилища должен реализовывать методы
_open()и_save(), а также любые другие методы, подходящие для вашего класса хранилища. Более подробную информацию об этих методах см. ниже.Кроме того, если ваш класс предоставляет локальное хранилище файлов, он должен переопределить метод
path(). - Ваш класс хранилища должен быть деконструируемым, чтобы его можно было сериализовать при использовании в поле миграции. Пока ваше поле имеет аргументы, которые сами по себе сериализуемы, вы можете использовать декоратор класса
django.utils.deconstruct.deconstructibleдля этого (это то, что Django использует для FileSystemStorage).
По умолчанию следующие методы вызывают NotImplementedError и обычно должны быть переопределены:
Однако не все эти методы являются обязательными и могут быть намеренно опущены. Так бывает, что каждый метод можно оставить нереализованным и при этом иметь работающее хранилище.
Например, если перечисление содержимого определённых хранилищ оказывается дорогостоящим, вы можете решить не реализовывать 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/1.11/howto/custom-file-storage/