Написание собственной системы хранения ¶
Если вам нужно предоставить настраиваемое хранилище файлов - распространенным примером является хранение файлов в какой-либо удаленной системе - вы можете сделать это, определив собственный класс хранилища. Вам нужно будет выполнить следующие действия:
Ваша пользовательская система хранения должна быть подклассом
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
( имя , режим = '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()
вызывается для получения альтернативного имени.