Creazione ed utilizzo delle Custom Actions in Django Admin
Ti è mai capitato di dover eseguire la medesima operazione su più elementi di
un elenco all'interno del backoffice? Hai mai avuto la necessità di aggiornare
lo status
degli ordini sul tuo ecommerce massivamente? Hai mai avuto la
necessità di rimuovere con un solo click elementi multipli?
Se la tua risposta alle precedenti domande è affermativa, sai benissimo che effettuare tali operazioni da backoffice, ripetendola singolarmente su ogni elemento, è un'operazione noiosa, lunga, e può facilmente portare ed errore umano. Sai che se l'operazione è di cancellazione, un errore potrebbe essere veramente grave e portarci via tantissimo tempo per ripristinare la situazione.
L'aggiornamento manuale è una strada assolutamente sconsigliabile a chiunque voglia fare le cose per bene senza incorrere in errori o problemi.
Un'alternativa all'aggiornamento manuale, potrebbe essere l'aggiornamento dei
dati lavorando direttamente con il database applicativo. Questo approccio,
tuttavia, ha molte controindicazioni: non sempre abbiamo accesso al database,
devi conoscere l'SQL
per eseguire le operazioni, un errore potrebbe seriamente
compromettere il nostro applicativo. Sebbene l'approccio è sicuramente
migliorativo rispetto all'aggiornamento manuale, non rappresenta una strada
sempre percorribile.
Come terza possibilità, puoi utilizzare uno strumento offerto dal framework Django all'interno dell'applicazione Django Admin.
Django Admin consente di eseguire operazioni massive su più elementi
attraverso l'implementazione delle custom actions. Ogni custom action
esegue l'operazione implementata dallo sviluppatore sugli elementi selezionati
del backoffice. Quindi potrai inserire l'operazione massiva desiderata
(aggiornamento status
, cancellazione elementi, modifica importo) ed
applicarla dinamicamente sugli elementi che selezioni dal backoffice Django
Admin.
In questo articolo vedrai come implementare una custom action su un campo
status
che contiene al suo interno delle etichette di stato (choices
). La
custom action modifica la proprietà status
del modello
Calciatore
da svincolato
a contrattualizzato
.
Creazione nel ModelAdmin
Puoi associare Una custom action ad un ModelAdmin
, inserendo il nome
dell'azione all'interno della lista actions
del ModelAdmin
sul quale vorrai
far comparire l'azione. Le azioni possono essere implementate sia all'interno
di funzioni sia come metodo di una classe.
Azione come funzione
Per aggiungere un'azione come funzione, inserirai l'elemento all'interno della lista come chiamata a funzione.
Il seguente frammento di codice mostra un esempio di definizione di custom action come funzione:
# implementazione della custom action come funzione
def nome_azione(modeladmin, request, queryset):
pass
@admin.register(Prodotto)
class ProdottoAdmin(admin.ModelAdmin):
actions = [nome_azione]
Azione come classe
Per aggiungere un'azione come metodo di una classe, l'inserimento
all'interno della lista actions
avviene indicando il nome del metodo
all'interno di una stringa.
Il seguente frammento di codice mostra come definire un'azione come metodo di una classe:
class ProdottoMixin:
def nome_azione(self, request, queryset):
pass
@admin.register(Prodotto)
class ProdottoAdmin(admin.ModelAdmin):
actions = ['nome_azione']
Creazione come funzione
Implementare la custom action come funzione consente di rendere
trasversale ai modelli l'implementazione. Per creare tale funzione,
all'interno del file admin.py
, dovrai inserire l'implementazione di una
funzione che preveda i seguenti parametri:
modeladmin
: rappresenta ilModelAdmin
considerato;request
: request generica con la quale si è richiesta la pagina di backoffice;queryset
: insieme di elementi sui quali eseguire l'azione
Il codice inserito all'interno della funzione effettua delle modifiche sugli elementi selezionati sul backoffice.
Facendo un esempio, selezionando gli elementi presenti nella lista sul
backoffice ed eseguendo il codice presente all'interno della funzione
contrattualizza
, sarà modificato lo status dei calciatori da svincolato
a
con_contratto
.
Il codice implementato all'interno della funzione è il seguente:
def contrattualizza(modeladmin, request, queryset):
num_items = queryset.update(status=Calciatore.CON_CONTRATTO)
modeladmin.message_user(
request,
f"Contrattualizzati {num_items} calciatori.",
messages.SUCCESS
)
All'interno della funzione è presente anche la chiamata al message_user
del modeladmin
che consente l'inserimento della barra di successo nella
quale sono proposti all'utente dei messaggi sull'esito dell'operazione
effettuata.
Come puoi evincere dal codice, la funzione esegue un update
dello status
portandolo al valore CON_CONTRATTO
; l'aggiornamento è eseguito sul queryset
selezionato dal backoffice Django.
Creazione come metodo di classe
Implementare la custom action come metodo di una classe consente di
utilizzare l'azione solamente estendendo la classe all'interno del
ModelAdmin
. I parametri di input sono allineati con quelli che sono inseriti
all'interno dell'azione implementata come funzione.
Proponendo un esempio, considerando la classe ContrattualizzaMixin
possiamo implementare la funzione contrattualizza_calciatore
per creare
l'azione.
class ContrattualizzaMixin:
def contrattualizza_calciatore(self, request, queryset):
num_items = queryset.update(status=Calciatore.CON_CONTRATTO)
self.message_user(
request,
f"Contrattualizzati {num_items} calciatori.",
messages.SUCCESS
)
Per inserire l'azione all'interno del ModelAdmin
inserire il seguente
codice:
class CalciatoreAdmin(admin.ModelAdmin, ContrattualizzaMixin):
actions = ['contrattualizza_calciatore']
Rinominare l'azione
Entrambe le soluzioni proposte, sia nell'implementazione come funzione che come metodo di classe, prevedono la possibilità di rinominare l'azione all'interno del pannello di amministrazione di Django Admin.
Per rinominare l'azione, valorizzare la proprietà short_description
come segue:
# implementazione come funzione
def nome_azione(...):
pass
nome_azione.short_description = 'Nuovo nome azione'
# implementazione come metodo di classe
class ProdottoMixin:
def nome_azione(...):
pass
nome_azione.short_description = 'Nuovo nome azione'
All'interno del backoffice Django appare a questo punto la short_description
definita e non più il nome della funzione o del metodo.
Conclusioni
Gli esempi mostrano come creare una custom action all'interno del pannello di amministrazione di Django Admin sia come funzione che come metodo di classe.
L'articolo mostra come aggiornare lo status di un modello calciatore, applicando le modifiche solo alle istanze selezionate dall'utente sul backoffice.