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