Funzione del parametro On_delete nei modelli Django
-
Argomento
CASCADE
-
Argomento
PROTECT
-
Argomento
RESTRICT
-
Argomento
SET_NULL
-
Argomento
SET_DEFAULT
-
Argomento
SET()
-
Argomento
DO_NOTHING
I modelli Django semplificano la creazione di database e tabelle, aggiungendo nuovi dati o tuple alle tabelle, eliminando, recuperando e modificando. Con i modelli Django, possiamo facilmente impostare relazioni tra tabelle con l’aiuto di chiavi esterne.
Quando si impostano le relazioni, dobbiamo impostare i valori per alcuni parametri. Uno di questi parametri è on_delete
. Il parametro on_delete
viene utilizzato per configurare il comportamento che dovrebbe essere adottato quando un oggetto referenziato viene eliminato. Viene fondamentalmente utilizzato per definire come verranno gestiti gli effetti della cancellazione di un oggetto referenziato.
Ci sono sette possibili comportamenti o azioni su cui può essere configurato il parametro on_delete
. Ne parleremo tutti individualmente.
Argomento CASCADE
Il comportamento a cascata viene generalmente utilizzato durante l’impostazione delle relazioni tra i modelli. Quando un oggetto referenziato viene eliminato, verranno eliminati anche tutti gli oggetti che fanno riferimento a quell’oggetto referenziato.
Sintassi
XYZ = models.ForeignKey(WASD, on_delete=models.CASCADE)
Per capirlo un po’ meglio, si consideri il seguente esempio. Nota che lo stesso esempio verrà utilizzato per spiegare anche altri comportamenti.
Esiste un sito Web in cui gli autori possono registrarsi e scrivere blog sul sito Web. Ora il rappresentare le due entità, considerare due modelli, vale a dire, Author
e Blog
. Tutte le voci o tuple in Blog
hanno un riferimento a una chiave esterna (o fanno riferimento) a una voce o tupla Author
. Rappresenta un rapporto che ogni blog è mai scritto appartiene a un autore che lo ha scritto.
Ora, supponiamo che il sito web abbia una politica che se un autore elimina il suo account, tutti i blog mai scritti da lui o lei verranno rimossi. In uno scenario del genere, una relazione a cascata sarà una scelta appropriata.
Argomento PROTECT
L’argomento PROTECT
impedisce la cancellazione dell’oggetto referenziato se ci sono oggetti che fanno riferimento a questo oggetto. In altre parole, l’oggetto a cui si fa riferimento non può essere eliminato finché esistono oggetti che lo referenziano. Gli oggetti di riferimento devono essere eliminati manualmente prima di eliminare l’oggetto di riferimento. La cancellazione viene impedita sollevando un ProtectedError
.
Questa relazione può essere utilizzata in luoghi in cui i dati sono molto importanti e sensibili e non puoi permetterti di perderli con una corretta gestione. O quando gli oggetti di riferimento vengono utilizzati anche da qualche altra parte e non possono essere eliminati senza un’adeguata convalida e gestione.
Argomento RESTRICT
RESTRICT
è simile a PROTECT
. Impedisce inoltre la cancellazione degli oggetti referenziati e solleva un RestrictedError
. Ma c’è una leggera differenza tra i due. A differenza di PROTECT
, se l’oggetto referenziato fa riferimento a qualche altro oggetto è una relazione CASCADE
e viene anche eliminato, l’eliminazione è consentita. In altre parole, l’eliminazione dell’oggetto referenziato è consentita se gli oggetti referenziati e l’oggetto referenziato fanno riferimento a qualche altro oggetto comune in una relazione CASCADE
.
Considera il seguente esempio.
class Artist(models.Model):
name = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
class Song(models.Model):
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
album = models.ForeignKey(Album, on_delete=models.RESTRICT)
Se proviamo a eliminare un oggetto Album
, verrà sollevato RestrictedError
. Ma se proviamo a eliminare un oggetto Artist
, l’eliminazione avrà successo, dato che le canzoni che fanno riferimento a un oggetto Album
fanno anche riferimento all’oggetto Artist
a cui fa riferimento l’oggetto Album
in una relationship
CASCADE.
Argomento SET_NULL
Nel caso di SET_NULL
, come suggerisce il nome, quando un oggetto referenziato viene eliminato, l’oggetto referenziato per tutti gli oggetti referenziati viene impostato su NULL
. Questa relazione richiede che il campo dell’oggetto a cui si fa riferimento sia nullable.
XYZ = models.ForeignKey(WASD, on_delete=models.SET_NULL, null=True)
Ad esempio, se il sito Web ha una politica che se un autore lascia, i suoi blog non verranno eliminati. Invece, l’autore per tutti i blog sarà impostato su un autore anonimo o None
.
Argomento SET_DEFAULT
Nel caso di SET_DEFAULT
, quando viene eliminato un oggetto referenziato, l’oggetto referenziato per tutti gli oggetti referenziati viene impostato su un valore predefinito. Questo valore predefinito può essere NULL
così come altri modelli o tabelle Django. Questa relazione richiede che il campo dell’oggetto a cui si fa riferimento sia nullable nel caso di NULL
.
XYZ = models.ForeignKey(WASD, on_delete=models.SET_DEFAULT, null=True, default=QWERTY)
Ad esempio, se il sito Web ha una politica secondo cui se un autore lascia, l’autore di tutti i suoi blog sarà l’amministratore o l’azienda stessa. In tali casi, SET_DEFAULT
sarebbe la scelta giusta.
Argomento SET()
SET()
è esattamente lo stesso di SET_DEFAULT
. Può accettare anche modelli o tabelle Django. L’unica differenza è che in SET()
, possiamo passare un callable, che sarà chiamato per tutti gli oggetti referenziati se l’oggetto referenziato viene cancellato.
XYZ = models.ForeignKey(WASD, on_delete=models.SET(...), null=True)
La funzione richiamabile, insieme a un modello, sarebbe simile a questa.
def getUser():
"""Callable function"""
return User.objects.get_or_create(username="anonymous")[0]
class Author(models.Model):
user = models.ForeignKey(User, on_delete=models.SET(getUser))
Argomento DO_NOTHING
DO_NOTHING
è una relazione un po’ rischiosa che può esistere tra due modelli. Come suggerisce il nome, quando un oggetto referenziato viene eliminato, l’oggetto referenziato non verrà modificato per tutti gli oggetti referenziati. In altre parole, non verrà fatto nulla per gestire gli effetti della cancellazione.
Questo è un comportamento molto rischioso in quanto può causare problemi di integrità perché l’oggetto a cui si fa riferimento viene eliminato, ma gli oggetti di riferimento continuano a farvi riferimento.
XYZ = models.ForeignKey(WASD, on_delete=models.DO_NOTHING)