¿Cómo hago una no igual en el filtrado de Django queryset?

En el modelo Django QuerySets, veo que hay un __gt y un __lt para los valores comparativos, pero ¿hay un __ne / != / ( No es igual a ?)

Quiero filtrar utilizando un no es igual a:

Ejemplo:

 Model: bool a; int x; 

quiero

 results = Model.objects.exclude(a=true, x!=5) 

La != No es la syntax correcta. Intenté __ne , .

Terminé usando:

 results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5) 

Tal vez los objetos Q podrían ser de ayuda para este problema. Nunca los he usado, pero parece que se pueden negar y combinar de forma muy parecida a las expresiones de python normales.

Actualización: Acabo de probarlo, parece funcionar bastante bien:

 >>> from myapp.models import Entry >>> from django.db.models import Q >>> Entry.objects.filter(~Q(id = 3)) [, , , ...] 

Su consulta parece tener un doble negativo, desea excluir todas las filas donde x no es 5, por lo que en otras palabras desea incluir todas las filas donde x es 5. Creo que esto hará el truco.

 results = Model.objects.filter(x=5).exclude(a=true) 

Para responder a su pregunta específica, no hay “no igual a”, pero eso es probablemente porque django tiene disponibles los métodos de “filtro” y “excluir”, por lo que siempre puede cambiar la lógica para obtener el resultado deseado.

la syntax de field=value en las consultas es una forma abreviada de field__exact=value . Es decir, Django coloca los operadores de consulta en los campos de consulta en los identificadores . Django soporta los siguientes operadores:

 exact iexact contains icontains in gt gte lt lte startswith istartswith endswith iendswith range year month day week_day isnull search regex iregex 

Estoy seguro de que combinando estos con los objetos Q como sugiere Dave Vogt y utilizando filter() o exclude() como Jason Baker sugiere que obtendrá exactamente lo que necesita para cualquier consulta posible.

Es fácil crear una búsqueda personalizada con Django 1.7. Hay un ejemplo de búsqueda __ne en la documentación oficial de Django .

Necesitas crear la búsqueda primero:

 from django.db.models import Lookup class NotEqual(Lookup): lookup_name = 'ne' def as_sql(self, qn, connection): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params return '%s <> %s' % (lhs, rhs), params 

Entonces necesitas registrarlo:

 from django.db.models.fields import Field Field.register_lookup(NotEqual) 

Y ahora puede utilizar la búsqueda __ne en sus consultas de esta manera:

 results = Model.objects.exclude(a=True, x__ne=5) 

En Django 1.9 / 1.10 hay tres opciones.

  1. Cadena exclude y filter

     results = Model.objects.exclude(a=true).filter(x=5) 
  2. Usa los objetos Q() y el operador ~

     from django.db.models import Q object_list = QuerySet.filter(~Q(a=True), x=5) 
  3. Registrar una función de búsqueda personalizada

     from django.db.models import Lookup from django.db.models.fields import Field @Field.register_lookup class NotEqual(Lookup): lookup_name = 'ne' def as_sql(self, compiler, connection): lhs, lhs_params = self.process_lhs(compiler, connection) rhs, rhs_params = self.process_rhs(compiler, connection) params = lhs_params + rhs_params return '%s <> %s' % (lhs, rhs), params 

    El decorador register_lookup se agregó en Django 1.8 y permite la búsqueda personalizada como de costumbre:

     results = Model.objects.exclude(a=True, x__ne=5) 

Mientras que con los modelos, puede filtrar con = , __gt , __gte , __lt , __lte , no puede usar ne __lte != O <> . Sin embargo, puede lograr un mejor filtrado utilizando el objeto Q.

Puede evitar el encadenamiento de QuerySet.filter() y QuerySet.exlude() , y usar esto:

 from django.db.models import Q object_list = QuerySet.filter(~Q(field='not wanted'), field='wanted') 

Decisión de diseño pendiente. Mientras tanto, use exclude()

El rastreador de problemas de Django tiene la notable entrada # 5763 , titulada “Queryset no tiene un” operador de filtro “no igual” . Es notable porque (a partir de abril de 2016) se “abrió hace 9 años” (en la edad de piedra de Django), “se cerró hace 4 años” y “se modificó por última vez hace 5 meses”.

Leer a través de la discusión, es interesante. Básicamente, algunas personas argumentan que se debe agregar __ne , mientras que otros dicen que exclude() es más claro y, por __ne tanto, no se debe agregar __ne .

(Estoy de acuerdo con el primero, porque el último argumento es aproximadamente equivalente a decir que Python no debería tener != Porque tiene == y aún not …)

Debes usar el filter y exclude así

 results = Model.objects.exclude(a=true).filter(x=5) 

Usando excluir y filtrar

 results = Model.objects.filter(x=5).exclude(a=true) 

El último bit de código excluirá todos los objetos donde x! = 5 y a es True. Prueba esto:

 results = Model.objects.filter(a=False, x=5) 

Recuerde, el signo = en la línea anterior está asignando Falso al parámetro a y el número 5 al parámetro x. No está comprobando la igualdad. Por lo tanto, realmente no hay forma de usar el símbolo! = En una llamada de consulta.

Lo que está buscando son todos los objetos que tienen ya sea a=false o x=5 . En Django, | Sirve como operador OR entre consultas:

 results = Model.objects.filter(a=false)|Model.objects.filter(x=5) 

  resultados = Model.objects.filter (a = True) .exclude (x = 5) 

Generetes este sql:

  seleccione * de tablex donde a! = 0 y x! = 5 

El SQL depende de cómo se representa su campo Verdadero / Falso y el motor de la base de datos. El código django es todo lo que necesitas.

Django-model-values (divulgación: autor) proporciona una implementación de la búsqueda NotEqual , como en esta respuesta . También proporciona soporte sintáctico para ello:

 from model_values import F Model.objects.exclude(Fx != 5, a=True) 

¡Cuidado con muchas respuestas incorrectas a esta pregunta!

La lógica de Gerard es correcta, aunque devolverá una lista en lugar de un queryset (lo que podría no importar).

Si necesita un queryset, use Q:

 from django.db.models import Q results = Model.objects.filter(Q(a=false) | Q(x=5))