Spec-Zone.ru › Django 5.1

Как создать пользовательский класс хранилища

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

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

_save(name, content)

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

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

get_valid_name(name)

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

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

get_alternative_name(file_root, file_ext)

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

get_available_name(name, max_length=None)

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

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

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

Использование вашего пользовательского движка хранилища

Первый шаг в использовании вашего пользовательского хранилища с Django — рассказать Django о файловом бэкэнде хранилища, который вы будете использовать. Это делается с помощью настройки STORAGES. Эта настройка сопоставляет псевдонимы хранилищ, которые представляют собой способ ссылаться на конкретное хранилище в Django, с словарем настроек для этого конкретного бэкэнда хранилища. Настройки во вложенных словарях полностью описаны в документации STORAGES.

Затем хранилища доступны по псевдониму из словаря django.core.files.storage.storages:

from django.core.files.storage import storages

example_storage = storages["example"]

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.1/howto/custom-file-storage/

Spec-Zone.ru

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