2010-03-11 37 views
19

¿Hay alguna diferencia entre filtro y exclusión en django? Si tengoDjango filter vs exclude

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

y quiero añadir otros criterios, es que hay una diferencia significativa entre a las dos líneas de código?

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

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

¿Se considera una mejor práctica o son las mismas tanto en función como en rendimiento?

Respuesta

16

Ambos se evalúan con holgura, por lo que espero que funcionen de manera equivalente. El SQL es probablemente diferente, pero sin distinción real.

+0

gracias. entonces es solo una cuestión de preferencia personal? Solo quería asegurarme de que no iba a hacer algo inexplicablemente estúpido. – Enrico

+2

@Enrico: No realmente, depende de lo que quieras. Ver mi respuesta El rendimiento no importa en este caso, son dos métodos que sirven para diferentes propósitos. Para la generación de SQL, la documentación dice acerca de '.exclude()': * Varios parámetros se unen a través de Y en la instrucción SQL subyacente, y todo se incluye en un NOT(). * –

+0

@Felix. Gracias. Supongo que mi pregunta principal, que podría haber comunicado con más claridad, fue sobre el rendimiento de ambos en django y finalmente en SQL. De su comentario de seguimiento, parece que uno podría funcionar mejor que el otro, pero principalmente basado en el SQL resultante. Sin embargo, al cambiar la segunda instrucción a '.exclude (user__isnull = True) .filter (modelField = x)', las dos declaraciones volverán a ser más o menos iguales. – Enrico

15

En general, excluir es opuesto al filtro. En este caso, ambos ejemplos funcionan de la misma manera.

aquí:

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

selecciona entradas que el usuario campo no es nulo y modelField tiene un valor x

En este caso:

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

primer lugar se selecciona entradas que modelField tiene valor x (tanto el usuario en nulo como el usuario no es nulo), entonces excluye las entradas que tienen el usuario de campo nulo.

Creo que en este caso sería mejor utilizar la primera opción, se ve más limpio. Pero ambos funcionan igual.

9

Depende de lo que desee lograr. Con los valores booleanos, es fácil cambiar entre .exclude() y .filter(), pero ¿qué ocurre, por ejemplo, con los valores booleanos? si desea obtener todos los artículos, excepto los de marzo? Se puede escribir la consulta como

Posts.objects.exclude(date__month=3) 

Con .filter() sería (pero no seguro si esto funciona en realidad):

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

o tendría que utilizar un objeto Q.

Como el nombre de la función ya se sugieren, .exclude() se utiliza para excluir conjuntos de datos desde el conjunto de resultados. Para valores booleanos, puede invertirlo fácilmente y usar .filter(), pero para otros valores esto puede ser más complicado.

Cuestiones relacionadas