Ricerca testuale su Django Admin usando Search Fields
La ricerca testuale è indispensabile per poter filtrare i dati in maniera efficiente, soprattutto quando il numero di informazioni, contenute nel nostro applicativo, cresce.
Django Admin offre la possibilità di aggiungere, all'interno del backoffice, i campi di ricerca in maniera intuitiva ed elegante. Con poche istruzioni, lo sviluppatore può mettere a disposizione dei propri utenti dei campi di ricerca che eseguono diverse tipologie di filtri: parola esatta, parole contenute, etc.
In questo articolo capirai come inserire i campi di ricerca all'interno
di Django Admin utilizzando il campo search_fields
. Una volta inseriti i
campi di ricerca, il backoffice di Django ci mostra una pagina che si presenta
come segue:
Attivazione della ricerca testuale
Per abilitare la ricerca testuale all'interno della pagina contenente l'elenco
degli elementi di un modello, inserire nella classe del ModelAdmin
del
modello, la seguente istruzione:
search_fields = ['colonna1', 'colonna2', ]
Nella precedente lista, colonna1
e colonna2
rappresentano i nomi dei campi
sui quali eseguiremo la ricerca testuale.
Ricerca su campi testuali
Un primo tipo di ricerca testuale può essere eseguito sui campi del modello di
tipo testuale: CharField
e TextField
. Per eseguire una ricerca di questo
tipo, inserire i nomi dei campi all'interno della variabile search_fields
.
Inserendo i nomi di colonne senza specificare nulla, il filtro
testuale lavora in modalità icontains
, ossia eseguendo una like
case insensitive.
Ad esempio, se inserisci una chiave di ricerca mario
e stai ricercando
sul campo nome
, la condizione eseguita sul database è:
where nome ilike '%mario%'
Ricerca su campi relazionati
Puoi eseguire ricerche sui campi relazionati mediante ForeignKey
e
ManyToManyField
. In particolare, puoi specificare il campo, della
tabella relazionata, sul quale eseguire la ricerca testuale.
Supponi di avere i seguenti modelli:
class Autore(models.Model):
nome = models.CharField(max_length=128)
cognome = models.CharField(max_length=128)
class Album(models.Model)
nome = models.CharField(max_length=128)
autore = models.ForeignKey(Autore, on_delete=models.PROTECT)
Potrai creare una ricerca testuale, sulla lista degli elementi di Album
,
sul campo nome
del modello Autore
, come segue:
class AlbumAdmin(admin.ModelAdmin):
search_fields = ['autore__nome']
La precedente notazione, contenente una lookup verso il campo nome
,
consente di ricercare testualmente, tramite icontains
, all'interno del campo
nome
del modello autore
.
Funzionamento della ricerca testuale
Dopo aver visto le modalità con le quali è possibile inserire una ricerca
all'interno dei ModelAdmin
, vediamo come opera la ricerca attivata
dall'istruzione search_fields
.
Supponi di avere il modello Autore
, descritto in precedenza, e di aver
definito le seguenti ricerche:
class AutoreAdmin(admin.ModelAdmin):
search_fields = ['nome', 'cognome']
Se inserisci la chiave di ricerca Tiziano Terzani
, la ricerca produce la
seguente condizione where
su SQL
:
where
(nome ILIKE '%Tiziano%' OR cognome ILIKE '%Tiziano%')
AND
(nome ILIKE '%Terzani%' OR cognome ILIKE '%Terzani%')
Puoi notare che ogni chiave inserita è ricercata all'interno dei campi, e deve essere presente in almeno un campo affinchè sia restituito l'elemento corrispondente.
Definizione lookup di ricerca
Dall'esempio del paragrafo precedente, si deduce che le ricerche testuali sono
eseguite mediante icontains
per default.
Django Admin consente tuttavia di utilizzare le seguenti lookup di ricerca:
startswith
iexact
oexact
search
startswith
La lookup startswith
consente di specificare il testo da ricercare all'inizio
del testo che si sta considerando. Una ricerca di questo tipo produce una
clausula where
come segue:
where nome ILIKE 'Pippo%'
iexact
o exact
La lookup iexact
o exact
consente di eseguire una ricerca puntuale della
chiave di ricerca inserita. Tale ricerca impone delle uguaglianze nella
clausola where
; è consigliabile utilizzarla solamente per ricerche che
prevedono una chiave singola, poiché chiavi di ricerca multiple restituiranno
sempre risultati nulli a meno che non si inseriscano chiavi che soddisfino
esattamente ogni singolo campo di ricerca sul quale è imposta la clausula
exact
.
search
La lookup search
esegue ricerche fulltext su campi con tipo
TextField
.
Le lookup di ricerca possono essere applicati sia a campi diretti del modello
considerato, sia a campi relazionati dal modello considerato. La notazione per
questi ultimi campi sarà del tipo modello__campo__lookup
.
Personalizzazione ricerca testuale
Django Admin consente la personalizzazione delle ricerche testuali mediante la
definizione nel ModelAdmin
del metodo get_search_results
.
Il metodo get_search_results
accetta in ingresso come parametri, la
request
, il queryset
ottenuto dai filtri fino alla chiamata del
metodo, e le chiavi di ricerca search_term
fornite dall'utente.
Il metodo restituisce una tupla contenente il queryset
filtrato e un
flag booleano che indica se i risultati contengono duplicati o meno.
L'implementazione di default prevede la ricerca all'interno dei campi definiti
da search_fields
.
Le ricerche eseguibili vanno dalla ricerca per numero interno alla ricerca su strumenti esterni quali Solr o Haystack.
Se ad esempio volessi imporre la ricerca intera sul campo anno_nascita
del modello Persona
, scriverai il seguente codice:
class PersonaAdmin(admin.ModelAdmin):
search_fields = ['nome']
def get_search_results(self, request, queryset, search_term):
queryset, use_distinct = \
super().get_search_results(request, queryset, search_term)
try:
search_term_as_int = int(search_term)
except ValueError:
pass
else:
queryset |= self.model.objects.filter(
anno_nascita=search_term_as_int
)
return queryset, use_distinct
Da notare che la specifica della ricerca per il campo anno_nascita
avviene all'interno del metodo e non del search_fields
.
Conclusioni
Gli esempi mostrati consentono di creare ricerche testuali all'interno del backoffice di Django Admin.