2010-03-11 18 views
19

Esiste una differenza tra filtro ed esclusione in django? Se hoFiltro Django vs escludi

self.get_query_set().filter(modelField=x) 

e voglio aggiungere un altro criterio, c'è una differenza significativa tra seguire due righe di codice?

self.get_query_set().filter(user__isnull=False, modelField=x) 

self.get_query_set().filter(modelField=x).exclude(user__isnull=True) 

è considerato una pratica migliore o è la stessa in entrambe le funzioni e le prestazioni?

risposta

16

Entrambi sono pigramente valutati, quindi mi aspetterei che funzionassero in modo equivalente. L'SQL è probabilmente diverso, ma senza distinzione reale.

+0

grazie. quindi è solo una questione di preferenze personali? Volevo solo assicurarmi che non avrei fatto qualcosa di inspiegabilmente stupido. – Enrico

+2

@Enrico: Non proprio, dipende da cosa vuoi. Vedi la mia risposta. Le prestazioni non contano in questo caso, sono due metodi che servono a scopi diversi. Per la generazione SQL, la documentazione dice di '.exclude()': * Più parametri vengono uniti tramite AND nell'istruzione SQL sottostante, e l'intera cosa è racchiusa in un NOT(). * –

+0

@Felix. Grazie. Credo che la mia domanda principale, che avrei potuto comunicare più chiaramente, riguardasse le prestazioni di entrambi in django e, in definitiva, in SQL. Dal tuo commento di follow-up, sembra che uno possa funzionare meglio dell'altro, ma principalmente basato sull'SQL risultante. Tuttavia, cambiando la seconda istruzione in '.exclude (user__isnull = True) .filter (modelField = x)' renderebbe quindi le due dichiarazioni più o meno uguali. – Enrico

15

In generale l'esclusione è l'opposto del filtro. In questo caso entrambi gli esempi funzionano allo stesso modo.

Qui:

self.get_query_set().filter(user__isnull=False, modelField=x) 

di selezionare le voci che l'utente campo non è nullo e modelField ha valore x

In questo caso:

self.get_query_set().filter(modelField=x).exclude(user__isnull=True) 

Prima di selezionare le voci che modelField ha valore x (sia l'utente in null che l'utente non è null), quindi si escludono le voci che hanno campo utente null.

Penso che in questo caso sarebbe meglio usare prima opzione, sembra più pulito. Ma entrambi funzionano allo stesso modo.

9

Dipende da ciò che si desidera ottenere. Con valori booleani è facile passare da .exclude() a .filter() ma, ad es. se vuoi ottenere tutti gli articoli ad eccezione di quelli di marzo? È possibile scrivere la query come

Posts.objects.exclude(date__month=3) 

Con .filter() sarebbe (ma io non so se questo funziona in realtà):

Posts.objects.filter(date__month__in=[1,2,4,5,6,7,8,9,10,11,12]) 

o si dovrebbe utilizzare un oggetto Q.

Come già suggerito dal nome della funzione, .exclude() viene utilizzato per esclude set di dati dal set di risultati. Per i valori booleani puoi facilmente invertirlo e usare invece .filter(), ma per altri valori questo può essere più complicato.