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

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. The FileNotFoundError exception should be raised when a file doesn’t exist.

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

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

New in Django 4.2.

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 the django.core.files.storage.storages dictionary:

from django.core.files.storage import storages

example_storage = storages["example"]
Back to Top