# documentación de Django - 5.2.8

# Cómo escribir una clase de almacenamiento personalizada

Si necesita proporcionar un almacenamiento de archivos personalizado -un ejemplo común es almacenar archivos en algún sistema de archivos remoto- puede hacerlo definiendo una clase de almacenamiento personalizada. Deberá seguir estos pasos:

1. Su sistema de almacenamiento personalizado debe heredar de `django.core.files.storage.Storage`:

       from django.core.files.storage import Storage

       class MyStorage(Storage): ...

2. Django debe ser capaz de crear una instancia de tu sistema de almacenamiento sin pasarle argumentos. Esto significa que cualquier ajuste debe ser tomado 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.

   Adicionalmente, si su clase proporciona almacenamiento local de archivos, debe redefinir el método `path()`.

4. Your storage class must be deconstructible so it can be serialized when it’s used on a field in a migration. As long as your field has arguments that are themselves serializable, you can use the `django.utils.deconstruct.deconstructible` class decorator for this (that’s what Django uses on FileSystemStorage).

Por defecto, los siguientes métodos generan `NotImplementedError` y normalmente tienen que ser redefinidos:

- `Storage.delete()`

- `Storage.exists()`

- `Storage.listdir()`

- `Storage.size()`

- `Storage.url()`

Nóte sin embargo que no todos estos métodos son requeridos y pueden ser omitidos. Como suele ocurrir, es posible dejar cada método sin ser implementado y tener un Storage funcional.

A modo de ejemplo, si listar los contenidos de ciertos backends de almacenamiento se vuelve costoso, puedes decidir no implementar `` Storage.listdir () “”.

Otro ejemplo sería un backend que solo contemple la escritura de archivos. En este caso, no necesitaría implementar ninguno de los métodos de arriba.

Por último, la implementación de estos métodos depende de usted. Dejar algunos métodos sin implementar darían una interfaz (posiblemente rota) parcial.

Por lo general, también querrá utilizar hooks diseñados específicamente para objetos de almacenamiento personalizado. Estos son:

_open(name, mode='rb')

Requerido

Llamado por `Storage.open()`, este es el verdadero mecanismo que utiliza la clase de almacenamiento para abrir el archivo. Esto debería retornar un objeto `File`, aunque en la mayoría de casos, querrás retornar alguna subclases aquí que implemente una lógica específica para el sistema de almacenamiento backend. La excepción `FileNotFoundError` debería generarse cuando un archivo no existe.

_save(name, content)

Llamado por `Storage.save()`. El `name` ya habrá pasado por `get_valid_name()` y `get_available_name()`, y el content` será un objeto `File` por sí mismo.

Debe devolver el nombre real del archivo guardado (generalmente el `nombre` ingresado, pero si el almacenamiento necesita cambiar el nombre del archivo, devuelve el nuevo nombre).

get_valid_name(name)

Devuelve un nombre de archivo adecuado para su uso con el sistema de almacenamiento subyacente. El argumento `name` pasado a este método es el nombre de archivo original enviado al servidor o, si `upload_to` es invocable, el nombre de archivo devuelto por ese método después de eliminar cualquier información de ruta. Redefina esto para personalizar cómo se convierten los caracteres no estándar en nombres de archivos seguros.

El código proporcionado en `Storage` conserva sólo caracteres alfanuméricos, puntos y guiones bajos del nombre de archivo original, eliminando todo lo demás.

get_alternative_name(file_root, file_ext)

Devuelve un nombre de archivo alternativo basado en los parámetros `file_root` y `file_ext`. De forma predeterminada, se agrega un guión bajo más una cadena alfanumérica aleatoria de 7 caracteres al nombre del archivo antes de la extensión.

get_available_name(name, max_length=None)

Devuelve un nombre de archivo que está disponible en el mecanismo de almacenamiento, posiblemente teniendo en cuenta el nombre de archivo proporcionado. El argumento `name` pasado a este método ya se habrá limpiado a un nombre de archivo válido para el sistema de almacenamiento, de acuerdo con el método `get_valid_name()` descrito anteriormente.

La longitud del nombre del archivo no excederá `max_length`, si se proporciona. Si no se puede encontrar un nombre de archivo único y disponible, se genera una excepción `SuspiciousFileOperation`.

Si ya existe un archivo con `nombre`, se llama a `get_alternative_name()` para obtener un nombre alternativo.

## Utilice su motor de almacenamiento personalizado

El primer paso para usar un almacenamiento personalizado es indicarle a Django el backend de almacenamientos de archivo que se usará. Esto se hace a través del parámetro `STORAGES` de la configuración. Este parámetro mapea los aliases del almacenamiento, que es una forma de relacionar un almacenamiento específico dentro de Django a un diccionario de configuraciones para el backend de almacenamiento específico. Los parámetros para dicho diccionario están descritos en su totalidad en la documentación `STORAGES`

Storages are then accessed by alias from the `django.core.files.storage.storages` dictionary:

    from django.core.files.storage import storages

    example_storage = storages["example"]