# Documentazione Django 5.2.8

# Come scrivere una storage class personalizzata

Se necessiti di utilizzare un file storage personalizzato – un esempio comune è salvare files su un sistema remoto – puoi farlo definendo una classe di storage personalizzata. Dovrai seguire i seguenti passi:

1. Il tuo sistema di storage personalizzato deve essere una sottoclasse di `django.core.files.storage.Storage`:

       from django.core.files.storage import Storage

       class MyStorage(Storage): ...

2. Django deve essere in grado di istanziare il tuo sistema di storage senza nessun argomento. Ciò significa che qualsiasi impostazione deve essere reperita da `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 tua classe di storage deve implementare i metodi `_open()` e `_save()`, insieme ad ogni altro metodo appropriato per la tua classe di storage. Vedi di seguito per sapere di più su questi metodi.

   In aggiunta, se la tua classe fornisce un file storage locale, deve sovrascrivere il metodo `path()`.

4. La tua classe di storage deve essere deconstructible così che possa essere serializzata quando è utilizzata in un campo all’interno di una migrazione. Fintanto che i tuoi campi hanno argomenti che sono essi stessi serializable, puoi usare il class decorator `django.utils.deconstruct.deconstructible` (è ciò che usa Django nel FileSystemStorage).

Di default, i metodi seguenti sollevano un «NotImplementedError» e devono essere sovrascritti.

- `Storage.delete()`

- `Storage.exists()`

- `Storage.listdir()`

- `Storage.size()`

- `Storage.url()`

Nota comunque che non tutti questi metodi sono necessari a posso essere deliberatamente omessi. Come succede, è possibile lasciare tutti i metodi non implementati e avere uno Storage funzionante.

A titolo di esempio, se fare la lista dei contenuti di alcuni backend di storage risulta dispendioso, potresti decidere di non implementare `Storage.listdir()`.

Un altro esempio potrebbe essere un backend che scrive solamente su file. In questo caso potrebbe non essere necessario implementare nessuno dei metodi sopracitati.

In ultimo, l’implementazione di questi metodi dipende da te. Lasciare alcuni metodi non implementati risulterà in un’interfaccia parziale (probabilmente non funzionante).

Generalmente vorrai anche usare un hook disegnato appositamente per gli oggetti del custom storage. Questi sono:

_open(name, mode='rb')

Richiesto.

Chiamato da `Storage.open()`, questo è il meccanismo effettivo utilizzato dalla classe di archiviazione per aprire il file. Questo deve restituire un oggetto `File`, anche se nella maggior parte dei casi vorrai restituire qui qualche sottoclasse che implementa la logica specifica del sistema di archiviazione backend. L’eccezione `FileNotFoundError` dovrebbe essere sollevata quando un file non esiste.

_save(name, content)

Chiamato da `Storage.save()`. `name` sarà già passato attraverso `get_valid_name()` e `get_available_name()`, e `content` sarà un oggetto `File` .

Dovrebbe restituire il nome effettivo del file salvato (di solito il `nome` passato, ma se l’archivio deve modificare il nome del file, restituire invece il nuovo nome).

get_valid_name(name)

Restituisce un nome di file idoneo all’uso con il sottostante sistema di memorizzazione. L’argomento `name` passato a questo metodo o è il nome del file inviato al server o, se `upload_to` è un metodo richiamabile, è il nome del file restituito da quel metodo dopo avere rimosso ogni informazione sul path. Effettua l’override di questo per personalizzare il modo di convertire i caratteri non-standard in nomi di file sicuri.

Il codice fornito in `Storage` conserva dai nomi originali dei file solo i caratteri alfanumerici, i punti e i trattini bassi, rimuovendo qualunque altra cosa.

get_alternative_name(file_root, file_ext)

Restituisce un nome del file alternativo basato sui parametrio `file_root` e `file_ext`. Di default, al nome del file viene appesa una stringa con un underscore e 7 caratteri casuali, prima dell’estensione.

get_available_name(name, max_length=None)

Restituisce un nome di file che sia disponibile nel sistema di memorizzazione, possibilmente prendendo in considerazione il nome del file fornito. L’argomento `name` passato a questo metodo dovrà essere già trasformato per essere un nome di file valido per il sistema di memorizzazione, in accordo al metodo `get_valid_name()` descritto precedentemente.

La lunghezza del nome del file non supererà `max_length`, se indicata. Se non sarà trovato un nome di file univoco libero, verrà sollevata una eccezione `SuspiciousFileOperation` .

se un file con «nome» esiste già, viene chiamato «get_alternative_name()» per ottenere un nome alternativo

## Utilizza il tuo motore di archiviazione personalizzato

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"]