Pergunta

Em Django Model QuerySets, vejo que existe um __gt e __lt para valores comparativos, mas existe um __ne/!=/<> (não é igual?)

Eu quero filtrar usando um não é igual:

Exemplo:

Model:
    bool a;
    int x;

Eu quero

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

o != não é a sintaxe correta. eu tentei __ne, <>.

Acabei usando:

results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)
Foi útil?

Solução

Pode ser Q objetos Pode ser útil para esse problema. Eu nunca os usei, mas parece que eles podem ser negados e combinados como expressões normais do Python.

ATUALIZAÇÃO: Eu apenas experimentei, 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>, ...]

Outras dicas

Sua consulta parece ter um duplo negativo, você deseja excluir todas as linhas onde X não é 5; portanto, em outras palavras, você deseja incluir todas as linhas onde X é 5. Acredito que isso fará 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 provavelmente porque o Django possui métodos "filtro" e "excluir" disponíveis, para que você sempre possa alternar a rodada lógica para obter o resultado desejado.

a field=value Sintaxe em consultas é uma abreviação para field__exact=value. Isto é, dizer isso 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 combinando -os com os objetos Q como Dave Vogt sugere e usando filter() ou exclude() Como Jason Baker sugere Você obterá exatamente o que precisa para qualquer consulta possível.

É fácil criar uma pesquisa personalizada com o Django 1.7. Há uma __ne Exemplo de pesquisa em 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

Então você precisa registrá -lo:

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

E agora você pode usar o __ne Pesquisa em suas consultas como esta:

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

Dentro Django 1.9/1.10 Existem três opções.

  1. Corrente exclude e filter

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

    from django.db.models import Q
    object_list = QuerySet.filter(~Q(a=True), x=5)
    
  3. Registro a 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_lookup Decorador foi adicionado em Django 1.8 e permite uma pesquisa personalizada como de costume:

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

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

Você pode evitar acorrentar QuerySet.filter() e QuerySet.exlude(), e use isto:

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

Decisão de design pendente. Enquanto isso, use exclude()

O rastreador de edição do django tem o notável Entrada #5763, intitulado "Queryset não tem um operador de filtro" não igual ". É notável porque (em abril de 2016) foi "aberto há 9 anos" (na Idade da Pedra de Django), "fechado há 4 anos" e "mudou pela última vez 5 meses atrás".

Leia a discussão, é interessante. Basicamente, algumas pessoas discutem __ne deve ser adicionado enquanto outros dizem exclude() é mais claro e, portanto, __nedeve não ser adicionado.

(Eu concordo com o primeiro, porque o último argumento é aproximadamente equivalente a dizer que Python não deveria ter != porque tem == e not já...)

Você deveria usar filter e exclude assim

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

Usando excluir e filtrar

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

O último bit de código excluirá todos os objetos em que x! = 5 e a é verdadeiro. Experimente isso:

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

Lembre -se, o = sinal na linha acima está atribuindo false ao parâmetro A e o número 5 ao parâmetro x. Não está checando a igualdade. Portanto, não há realmente nenhuma maneira de usar o símbolo! = Em uma chamada de consulta.

O que você está procurando são todos objetos que têm a=false ou x=5. Em Django, | serve como OR Operador entre os consultas:

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

results = Model.objects.filter(a = True).exclude(x = 5)
Genetes este SQL:
select * from tablex where a != 0 and x !=5
O SQL depende de como seu campo verdadeiro/falso é representado e do mecanismo de banco de dados. O código Django é tudo o que você precisa.

Valores Django-Modelo (Divulgação: Autor) fornece uma implementação do Não igual 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)

Cuidado com muitas respostas incorretas para esta pergunta!

A lógica de Gerard está correta, embora retorne uma lista em vez de uma consulta (o que pode não importar).

Se você precisar de uma consulta, use Q:

from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top