Ricerche inverse di chiavi esterne in Django
Django è un framework di sviluppo web efficiente che semplifica la creazione di applicazioni web. Django semplifica la gestione dell’autenticazione e dell’autorizzazione, la creazione di modelli HTML, la gestione di file statici, l’interazione con i database e l’esecuzione di operazioni CRUD su di essi.
Parlando di database, Django semplifica la maggior parte delle query che puoi fare mentre lavori con i database. Una di queste query è l’aspetto inverso; un esempio è quando dobbiamo ottenere tutti gli oggetti di una tabella che fanno riferimento a un particolare record della stessa tabella o di un modello diverso.
Questo articolo mostrerà quanto sia semplice eseguire ricerche inverse di chiavi esterne in Django.
Ricerche inverse nei modelli Django
Prima di passare alla fase vera e propria, abbiamo bisogno di alcuni modelli o tabelle per la dimostrazione. Prenderemo in considerazione due entità: insegnante e studente. Lo studente ha due tipi di insegnanti; un insegnante di classe e un insegnante preferito. Il modello Student
fa riferimento al modello Teacher
.
from django.db import models
class Teacher(models.Model):
name = models.CharField(max_length=200)
subject = models.CharField(max_length=200)
class Student(models.Model):
name = models.CharField(max_length=200)
classTeacher = models.ForeignKey(
Teacher, on_delete=models.SET_NULL, null=True, related_name="classTeacherOf"
)
favouriteTeacher = models.ForeignKey(
Teacher, on_delete=models.SET_NULL, null=True, related_name="favouriteTeacherOf"
)
Due campi del modello Student
fanno riferimento al modello Teacher
. In Django, quando si fa riferimento allo stesso modello più di una volta, dobbiamo fornire un “nome_correlato” per tutti i campi perché il “nome_correlato” predefinito di Django per un singolo campo di riferimento si scontra con altri campi di riferimento. In caso contrario, Django genererà un’eccezione.
Il related_name
è quello che usiamo per la ricerca inversa. In generale, è una buona pratica fornire un related_name
per tutte le chiavi esterne invece di usare il nome di default di Django.
Esempio 1
Abbiamo un insegnante il cui id
è 1
. Se dobbiamo ottenere tutti gli studenti che hanno questo individuo come insegnante di classe, faremo quanto segue:
teacher = Teacher.objects.get(id=1)
students = teacher.classTeacherOf.all()
print(students) # A QuerySet of Student objects
Nota come stiamo usando il related_name
. Il teacher.classTeacherOf
è un oggetto manager, il che significa che chiamiamo metodi come all()
, filter()
, exclude()
su di esso.
Esempio 2
Abbiamo un insegnante il cui id
è 6
. Se dobbiamo prendere tutti gli studenti che considerano questo insegnante il loro insegnante preferito, faremo qualcosa del genere:
teacher = Teacher.objects.get(id=6)
students = teacher.favouriteTeacherOf.all()
print(students) # A QuerySet of Student objects
Esempio 3
Abbiamo un insegnante il cui id
è 25
. Se dobbiamo verificare se questo insegnante è l’insegnante di classe di uno studente il cui id
è 5
, faremo qualcosa come segue:
teacher = Teacher.objects.get(id=25)
student = teacher.classTeacherOf.filter(id=5)
print(student) # A QuerySet of either 1 or 0 Student
Si noti che se non vengono trovati oggetti nella ricerca inversa, viene restituito un QuerySet
vuoto.