Como escrever uma classe de armazenamento customizada¶
Se você precisa de um armazenador de arquivos customizados – um exemplo comum é armazenar arquivos em algum sistema remoto – você pode faze-lo definido uma classe de armazenamento customizada. Você precisará seguir estes passos:
O seu Sistema de armazenamento customizado deve ser uma subclasse de
django.core.files.storage.Storage
:from django.core.files.storage import Storage class MyStorage(Storage): ...
Django deve ser capaz de instanciar o seu sistema de armazenamento sem nenhum argumento. Isso significa que quaisquer definições devem ser tomada a partir de
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 ...
A classe de armazenamento deve implementar os métodos
_open()
e_save()
, além de qualquer outro método apropriado para a sua classe de armazenamento. Veja abaixo mais sobre estes métodos.Além disso, se sua classe permite armazenamento local de arquivo, deve-se sobrescrever o método
path()
.Sua classe de armazenamento deve ser “desconstruível” para que possa ser “serializado” quando usado em um campo na “migration”. Uma vez que seus campos têm argumentos que são eles mesmos serializáveis, é possível usar o “decorator” de classe
django.utils.deconstruct.deconstructible
para isso (que é usado pelo Django no FileSystemStorage).
Por padrão, os seguintes métodos levantam NotImplementedError
e normalmente terão de ser sobrescritas:
Note porém que nem todos estes métodos são requeridos e talvez deliberadamente omitidos. Caso isso ocorra, é possível deixar cada método não implementado e ainda ter um armazenamento que funcione.
A título de exemplo, listando o conteúdo de um certo armazenamento backend acaba se tornando custoso, você pode decidir por não implementar Storage.listdir()
.
Outro exemplo seria um backend que só lida com a escrita de arquivos. Neste caso, não seria necessário implementar qualquer um dos métodos acima.
Em última análise, quais destes métodos são implementados depende de você. Deixando de implementar alguns métodos irá resultar em uma interface parcial (possivelmente quebrada).
Você também pode querer usar hooks feitos especificamente para objetos de storage personalizados. Estes são os seguintes:
-
_open
(name, mode='rb')¶
Obrigatório.
Called by Storage.open()
, this is the actual mechanism the storage class
uses to open the file. This must return a File
object, though in most cases,
you’ll want to return some subclass here that implements logic specific to the
backend storage system. The FileNotFoundError
exception should be raised
when a file doesn’t exist.
-
_save
(name, content)¶
Chamado por `` Storage.save () . O `` name
já terá passado por `` get_valid_name ()`` e get_available_name ()
, e o content
será ele mesmo um objeto File
.
Should return the actual name of the file saved (usually the name
passed
in, but if the storage needs to change the file name return the new name
instead).
-
get_valid_name
(name)¶
Retorna um nome de arquivo adequado para uso com o sistema de armazenamento subjacente. O argumento name
passado para esse método é o nome do arquivo original enviado para o servidor ou, se `` upload_to`` é um “callable” (método), o nome do arquivo retornado por esse método depois de qualquer informação de caminho ser removido. Sobrescreva isso para customizar como caracteres fora de padrão são convertidos para nomes de arquivos seguros.
O código fornecido em Storage
guarda apenas os caracteres alfanuméricos, pontos e “underscore” do nome do arquivo original, removendo qualquer outra cosa.
-
get_alternative_name
(file_root, file_ext)¶
Retorna um nome de arquivo alternativo baseado nos parâmetros de file_root
e file_ext
. Por padrão, um “underscore” e uma string de 7 caracteres alfanuméricos aleatórios são acrescentados antes da extensão.
-
get_available_name
(name, max_length=None)¶
Retorna um nome de arquivo que está disponível no mecanismo de armazenamento, possivelmente levando em conta o nome do arquivo fornecido. O argumento name
passado para este método já terá sido limpo para um nome de arquivo válido para o sistema de armazenamento, de acordo com o método get_valid_name()
descrito acima.
O comprimento do nome do arquivo não será superior a `` max_length``, se informado. Se um nome de arquivo único não pode ser encontrado, a: exc: `SuspiciousFileOperation <django.core.exceptions.SuspiciousOperation> `Exceção é gerada.
Se um arquivo name
já existe, get_alternative_name()
é chamado para obter um nome alternativo.
Use seu mecanismo de armazenamento personalizado¶
The first step to using your custom storage with Django is to tell Django about
the file storage backend you’ll be using. This is done using the
STORAGES
setting. This setting maps storage aliases, which are a way
to refer to a specific storage throughout Django, to a dictionary of settings
for that specific storage backend. The settings in the inner dictionaries are
described fully in the STORAGES
documentation.
Storages are then accessed by alias from from the
django.core.files.storage.storages
dictionary:
from django.core.files.storage import storages
example_storage = storages["example"]