Como eu faço um não é igual em filtragem queryset Django?

votos
480

No Django QuerySets modelo, vejo que há um __gte __ltpara valores comparativos, mas há uma __ne/ !=/ <>( não é igual ?)

Eu quero filtrar usando um não é igual a:

Exemplo:

Model:
    bool a;
    int x;

eu quero

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

A !=não é sintaxe correta. Eu tentei __ne, <>.

Acabei usando:

results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)
Publicado 26/03/2009 em 20:47
fonte usuário
Em outras línguas...                            


14 respostas

votos
502

Talvez objetos Q poderia ser de ajuda para este problema. Eu nunca usei-los, mas parece que eles podem ser negados e combinou muito parecido com expressões Python normais.

Update: Eu apenas tentei sair, parece funcionar muito bem:

>>> 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>, ...]
Respondeu 20/07/2009 em 18:58
fonte usuário

votos
456

Sua consulta parece ter uma dupla negativa, você quiser excluir todas as linhas onde x não é 5, mas em outras palavras você quiser incluir todas as linhas onde x é 5. Eu acredito que isso vai fazer o truque.

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

Para responder à sua pergunta específica, não há "não é igual a", mas que é provavelmente porque o Django tem tanto "filtro" e "excluir" métodos disponíveis para que você sempre pode apenas mudar a lógica rodada para obter o resultado desejado.

Respondeu 10/11/2010 em 00:56
fonte usuário

votos
96

a field=valuesintaxe em consultas é um atalho para field__exact=value. Isso quer dizer que Django coloca operadores de consulta em campos de consulta nos identificadores . Django suporta os seguintes operadores:

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

Tenho certeza de que, combinando-os com os objetos q como Dave Vogt sugere e usando filter()ou exclude()como Jason Baker sugere que você obtenha exatamente o que você precisa para praticamente qualquer consulta possível.

Respondeu 20/07/2009 em 19:07
fonte usuário

votos
60

É fácil criar uma pesquisa personalizada com Django 1.7. Há um __neexemplo de pesquisa na documentação oficial do Django .

Você precisa criar a pesquisa em si primeiro:

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

Em seguida, você precisa registrá-lo:

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

E agora você pode usar a __nepesquisa em suas consultas como este:

results = Model.objects.exclude(a=True, x__ne=5)
Respondeu 24/03/2015 em 08:07
fonte usuário

votos
49

Em Django 1.9 / 1.10 há três opções.

  1. cadeia excludeefilter

    results = Model.objects.exclude(a=true).filter(x=5)
    
  2. Use Q()objetos e o ~operador

    from django.db.models import Q
    object_list = QuerySet.filter(~Q(a=True), x=5)
    
  3. Registrar uma função de pesquisa 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
    

    O register_lookupdecorador foi adicionado em Django 1.8 e permite pesquisa de costume, como de costume:

    results = Model.objects.exclude(a=True, x__ne=5)
    
Respondeu 24/02/2016 em 13:12
fonte usuário

votos
37

Enquanto com os modelos, você pode filtrar com =, __gt, __gte, __lt, __lte, você não pode usar ne, !=ou <>. No entanto, você pode conseguir uma melhor filtragem sobre como usar o objeto Q.

Você pode evitar o encadeamento QuerySet.filter()e QuerySet.exlude(), e usar este:

from django.db.models import Q
object_list = QuerySet.filter(~Q(field='not wanted'), field='wanted')
Respondeu 18/01/2011 em 15:34
fonte usuário

votos
13

Pendente de decisão design. Enquanto isso, useexclude()

O issue tracker Django tem a notável entrada # 5763 , intitulado "A Queryset não tem um '' operador de filtro" não é igual . É notável porque (a partir de abril de 2016) era "aberta há 9 anos" (na idade da pedra Django), "fechado há 4 anos", e "modificado pela última vez 5 meses atrás".

Leia através da discussão, é interessante. Basicamente, algumas pessoas argumentam __nedeve ser adicionado enquanto outros dizem que exclude()é mais clara e, portanto, __ne deve não ser adicionados.

(Eu concordo com o anterior, porque o último argumento é mais ou menos equivalente a dizer Python não deve ter !=porque tem ==e notjá ...)

Respondeu 21/04/2016 em 08:44
fonte usuário

votos
12

Você deve usar filtere excludecomo esta

results = Model.objects.exclude(a=true).filter(x=5)
Respondeu 25/09/2015 em 08:52
fonte usuário

votos
7

O último pedaço de código irá excluir todos os objetos onde x! = 5 e um é verdadeiro. Tente isto:

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

Lembre-se, o sinal = na linha acima está atribuindo Falso para o parâmetro de um e do número 5 para o parâmetro x. Não é a verificação de igualdade. Assim, não há realmente nenhuma maneira de usar o! = Símbolo em uma chamada de consulta.

Respondeu 26/03/2009 em 20:54
fonte usuário

votos
3

Usando excluir e filtro

results = Model.objects.filter(x=5).exclude(a=true)
Respondeu 12/07/2018 em 10:43
fonte usuário

votos
3

Resultados = Model.objects.filter (a = TRUE) .exclude (x = 5)
Generetes esse SQL:
SELECT * FROM tablex onde um! = 0 e x! = 5
O SQL depende de como seu Verdadeiro / Falso campo é representado, e o motor de banco de dados. O código Django é tudo que você precisa embora.

Respondeu 22/02/2017 em 12:12
fonte usuário

votos
3

O que você está procurando estão todos os objetos que têm tanto a=false ou x=5 . No Django, |serve como ORoperador entre QuerySets:

results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
Respondeu 27/06/2016 em 12:50
fonte usuário

votos
2

Django-modelo valores (divulgação: autor) fornece uma implementação da NotEqual pesquisa, como em esta resposta . Ele também fornece suporte sintático para ele:

from model_values import F
Model.objects.exclude(F.x != 5, a=True)
Respondeu 13/01/2018 em 03:23
fonte usuário

votos
0

Cuidado com os lotes de respostas incorretas a esta pergunta!

A lógica de Gerard está correto, embora ele irá retornar uma lista em vez de um queryset (que pode não importa).

Se você precisa de um queryset, utilize Q:

from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))
Respondeu 14/03/2019 em 16:21
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more