Segnali in django, come e perché utilizzarli

Segnali in django, come e perché utilizzarli

Se non hai mai sentito parlare dei segnali in django significa che non stai sfruttando una delle funzionalità più utili ed interessanti.

Nello sviluppo di un software capita spesso di trovarsi nella situazione di dover effettuare determinate operazioni al verificarsi di determinate condizioni.

Supponiamo di voler associare un codice univoco a ogni nuovo cliente.

Uno dei possibili approcci è di definire una funzione da richiamare durante la creazione di un nuovo oggetto.

import uuid

def create_random_code():
    code = uuid.uuid4().hex[:15].upper()

    return code
customer.unique_code = create_random_code()
customer.save()

Questo sistema presuppone che ogni qual volta all’interno del codice venga creato un nuovo oggetto di tipo customer sia necessario ricordare di richiamare la specifica funzione.

Non è difficile pensare che, soprattutto a distanza di mesi, possa capitare di dimenticarsi. Oppure il caso di un nuovo sviluppatore appena inserito nel team che non è a conoscenza di questa cosa.

E’ possibile fare in modo che alla creazione di un nuovo oggetto di tipo customer in automatico django generi un codice univoco e glielo assegni? La risposta è si e i segnali ci vengono in aiuto in questo senso.

Django possiede al suo interno un signal dispatcher che permette all’applicazione di “accorgersi” quando un determinato evento si verifica.

Possiamo quindi intercettare questo segnale ed eseguire una serie di operazioni.

Sono già disponibili una serie di segnali predefiniti. Ti rimando alla documentazione ufficiale per verificare quelli disponibili out-of-the-box.

Ai fini di questo post limitiamoci a vedere l’esempio relativo al segnale pre_save che ci permette di intercettare l’evento di salvataggio di un model.

Ti segnalo anche l’esistenza del segnale post_save. La differenza tra pre e post, come il nome può suggerire, è che il primo viene lanciato prima dell’operazione di salvataggio vera e propria mentre il secondo viene lanciato una volta completato il salvataggio su db.

Il risultato che vogliamo ottenere è che ogni qual volta all’interno del codice salveremo un oggetto di tipo customer, prima che questo venga effettivamente salvato sul db, venga generato un codice univoco e che venga assegnato all’oggetto che stiamo per salvare.

Spostiamoci quindi nel file models.py nel quale risiede il model per l’oggetto customer e importiamo la seguente classe:

from django.db.models.signals import pre_save

In fondo al file aggiungiamo quindi la seguente funzione:

def create_customer(sender, instance, **kwargs):
    if instance._state.adding is True:
        code = uuid.uuid4().hex[:15].upper()

        instance.customer_code = code

Vediamo alcuni dettagli da considerare.

Facciamo subito un controllo sulla seguente proprietà:

instance._state.adding

L’oggetto instance è l’istanza del model che stiamo andando a salvare.

La proprietà _state.adding, se settata a True, indica che l’oggetto è stato creato.

Definita la funzione dobbiamo collegarla al relativo segnale.

E’ importante verificare questa condizione perché altrimenti questa operazione verrebbe eseguita a ogni salvataggio dell’oggetto andando quindi ogni volta a sovrascrivere il codice precedentemente generato.

Aggiungiamo quindi la seguente istruzione:

pre_save.connect(create_customer, sender=Customer)

In questo modo stiamo connettendo il segnale pre_save alla funzione create_customer.

Il parametro sender indica il tipo di oggetto che deve essere monitorato per l’esecuzione della funzione create_customer.

Così facendo ogni qual volta, in qualsiasi parte del codice, andremo a creare un nuovo oggetto di tipo customer, in automatico django saprà che prima di effettuare il salvataggio vero e proprio a db dovrà generare un codice da inserire nella relativa proprietà.

Questo approccio presenta diversi vantaggi come la possibilità di centralizzare il codice in un unico punto ed evitare possibili errori umani durante lo sviluppo.

In questo post ho voluto presentarti uno dei segnali più utilizzati ma come spiegato sopra django possiede al suo interno un numero importante di segnali già pronti all’uso.

Lo scopo è quello di introdurre l’argomento per dimostrare quali sono le potenzialità di questo framework.

Ti rimando quindi alla documentazione ufficiale per scoprire quali sono i segnali già esistenti e come è possibile utilizzarli.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *