# Documentação Django 6.0.7

# 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:

1. 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): ...

2. 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
               ...

3. Your storage class must implement the `_open()` and `_save()` methods, along with any other methods appropriate to your storage class. See below for more on these methods.

   Além disso, se sua classe permite armazenamento local de arquivo, deve-se sobrescrever o método `path()`.

4. 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:

- `Storage.delete()`

- `Storage.exists()`

- `Storage.listdir()`

- `Storage.size()`

- `Storage.url()`

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.

Chamado por `Storage.open()`, esse é o mecanismo pela qual a classe storage utiliza para abrir o arquivo. Isso deve retornar um objeto `File`, porém, na maioria dos casos você desejará retornar aqui alguma subclasse que implemente a lógica específica para o sistema de armazenamento do back-end. O `FileNotFoundError` exception deveria ser lançada quando um arquivo não existe.

_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`.

Deveria retornar o nome atual do arquivo salvo (normalmente o `name` passado, mas se o storage precisa alterar o nome do arquivo, então é retornado o novo nome).

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

O primeiro passo para utilizar seu armazenamento customizado com o Django é dizer para o Django sobre o backend de armazenamento de arquivos que você estará utilizando. Isso é feito utilizando a configuração `STORAGES`. Essa configuração mapeia apelidos de armazenamento, que são uma maneira de referenciar um armazenamento específico no Django, para um dicionário de configuração para aquele backend de armazenamento específico. As configurações nos dicionários internos são descritas por completo na documentação `STORAGES`.

Armazenamentos são então acessados por apelido no dicionário `django.core.files.storage.storages`:

    from django.core.files.storage import storages

    example_storage = storages["example"]