# documentación de Django - 3.2.11.dev

# Creación de sistema de almacenamiento personalizado

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. La clase de almacenamiento deberá implementar los métodos `_open()` y `_save()`, junto con cualquier otro método apropiado para tu clase de almacenamiento. Consulte a continuación para obtener más información sobre estos métodos.

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

4. La clase de almacenamiento debe ser deconstruible para que pueda ser serializada al usarse en un campo en una migración. Siempre y cuando el campo tenga argumentos que sean serializables por sí mismos, puedes usar el decorador de clase `django.utils.deconstruct.deconstructible` con este propósito (es lo que Django usa en FileSystemStorage).

By default, the following methods raise `NotImplementedError` and will typically have to be overridden:

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

You’ll also usually want to use hooks specifically designed for custom storage objects. These are:

`_open`(name, mode='rb')

Requerido

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.

`_save`(name, content)

Called by `Storage.save()`. The `name` will already have gone through `get_valid_name()` and `get_available_name()`, and the `content` will be a `File` object itself.

Should return the actual name of 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)

Returns a filename suitable for use with the underlying storage system. The `name` argument passed to this method is either the original filename sent to the server or, if `upload_to` is a callable, the filename returned by that method after any path information is removed. Override this to customize how non-standard characters are converted to safe filenames.

The code provided on `Storage` retains only alpha-numeric characters, periods and underscores from the original filename, removing everything else.

`get_alternative_name`(file_root, file_ext)

Returns an alternative filename based on the `file_root` and `file_ext` parameters. By default, an underscore plus a random 7 character alphanumeric string is appended to the filename before the extension.

`get_available_name`(name, max_length=None)

Returns a filename that is available in the storage mechanism, possibly taking the provided filename into account. The `name` argument passed to this method will have already cleaned to a filename valid for the storage system, according to the `get_valid_name()` method described above.

The length of the filename will not exceed `max_length`, if provided. If a free unique filename cannot be found, a `SuspiciousFileOperation` exception is raised.

If a file with `name` already exists, `get_alternative_name()` is called to obtain an alternative name.