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


En el modelo de QuerySets de Django, veo que hay un __gt y __lt para valores comparativos, pero ¿hay algún __ne/!=/<> (no es igual?)

Quiero filtrar usando un no igual a:

Ejemplo:

Model:
    bool a;
    int x;

yo quiero

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

los != no es la sintaxis correcta Lo intenté __ne, <>.

Terminé usando:

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

504
2018-03-26 19:47


origen


Respuestas:


Tal vez Q objetos podría ser de ayuda para este problema. Nunca los he usado, pero parece que pueden ser negados y combinados de manera similar a las expresiones normales de Python.

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))

[<Entry: Entry object>, <Entry: Entry object>, <Entry: Entry object>, ...]

521
2017-07-20 17:58



Su consulta parece tener un doble negativo, quiere excluir todas las filas donde x no es 5, por lo tanto, en otras palabras, desea incluir todas las filas donde x IS 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 probablemente sea porque django tiene métodos de "filtro" y "exclusión" disponibles, por lo que siempre puede cambiar la ronda lógica para obtener el resultado deseado.


470
2017-11-09 23:56



el field=value la sintaxis en las consultas es una forma abreviada de field__exact=value. Es decir que Django pone operadores de consulta en campos de consulta en los identificadores. Django admite 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 al combinar esto con los objetos Q Dave Vogt sugiere y usando filter() o exclude() como Jason Baker sugiere obtendrá exactamente lo que necesita para casi cualquier consulta posible.


98
2017-07-20 18:07



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

Primero debe crear la búsqueda:

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 puedes usar el __ne busque en sus consultas de esta manera:

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

66
2018-03-24 08:07



En Django 1.9 / 1.10 hay tres opciones

  1. Cadena exclude y filter

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

    from django.db.models import Q
    object_list = QuerySet.filter(~Q(a=True), x=5)
    
  3. Registra un 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
    

    los register_lookup decorador fue agregado en Django 1.8 y permite la búsqueda personalizada como de costumbre:

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

55
2018-02-24 13:12



Mientras que con los Modelos, puedes filtrar con =, __gt, __gte, __lt, __lte, no puede utilizar ne, != o <>. Sin embargo, puede lograr un mejor filtrado al usar el objeto Q.

Puedes evitar encadenar QuerySet.filter() y QuerySet.exlude()y usa esto:

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

39
2018-01-18 14:34



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

El rastreador de problemas de Django tiene el notable entrada # 5763, noble "Queryset no tiene un operador de filtro" no igual ". Es notable porque (desde abril de 2016) fue "abierto hace 9 años" (en la edad de piedra de Django), "cerrado hace 4 años", y "cambió por última vez hace 5 meses".

Lea la discusión, es interesante. Básicamente, algunas personas discuten __ne debería ser añadido mientras que otros dicen exclude() es más claro y por lo tanto __ne debería no ser agregado.

(Estoy de acuerdo con el primero, porque el último argumento es más o menos equivalente a decir que Python no debería tener !=porque Tiene == y not ya...)


14
2018-04-21 08:44



Deberías usar filter y exclude Me gusta esto

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

12
2017-09-25 08:52



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

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

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


7
2018-03-26 19:54



Lo que estás buscando son todos los objetos que tienen a=false  o  x=5. En Django, | sirve como OR operador entre querysets:

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

3
2018-06-27 12:50