Domanda

In Django querysets modello, vedo che c'è un __gt e __lt per i valori Comparati, ma c'è un __ne / != / <> ( non uguali ?)

Voglio filtrare utilizzando un non uguale:

Esempio:

Model:
    bool a;
    int x;

Voglio

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

Il != non è sintassi corretta. Ho provato __ne, <>.

Ho finito per usare:

results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)
È stato utile?

Soluzione

Q potrebbe essere di aiuto per questo problema. Non li ho mai usato ma sembra che possano essere annullati e combinati molto simile a normali espressioni Python.

Aggiornamento: ho appena provato fuori, sembra funzionare abbastanza bene:

>>> 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>, ...]

Altri suggerimenti

La vostra richiesta sembra avere una doppia negazione, si desidera escludere tutte le righe in cui x non è 5, quindi in altre parole si desidera includere tutte le righe in cui X è 5. Credo che questo farà il trucco.

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

Per rispondere alla tua domanda specifica, non v'è alcuna "non uguale a", ma questo è probabilmente perché Django ha sia "filtro" e "escludere" metodi disponibili in modo da poter sempre basta passare la logica turno per ottenere il risultato desiderato.

la sintassi field=value nelle query è una scorciatoia per field__exact=value. Vale a dire che Django mette operatori di query su campi di query nel identificatori . Django supporta i seguenti operatori:

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

Sono sicuro che combinando questi con gli oggetti Q come Dave Vogt suggerisce e utilizzando filter() o exclude() come Jason Baker suggerisce si otterrà esattamente ciò che serve per quasi ogni possibile richiesta.

E 'facile creare una ricerca personalizzata con Django 1.7. C'è un esempio di ricerca __ne in Django documentazione ufficiale .

È necessario creare la ricerca in sé prima:

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

Allora avete bisogno di registrarlo:

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

E ora è possibile utilizzare la ricerca __ne nelle query in questo modo:

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

Nel Django 1.9 / 1.10 ci sono tre opzioni.

  1. exclude Catena e filter

    results = Model.objects.exclude(a=true).filter(x=5)
    
  2. Q() oggetti ~

    from django.db.models import Q
    object_list = QuerySet.filter(~Q(a=True), x=5)
    
  3. Registra un funzione

    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
    

    Il decoratore register_lookup è stato aggiunto in Django 1.8 e consente di ricerca personalizzata come al solito:

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

Mentre con i modelli, è possibile filtrare con =, __gt, __gte, __lt, __lte, non è possibile utilizzare ne, != o <>. Tuttavia, è possibile ottenere una migliore filtraggio utilizzando l'oggetto Q.

È possibile evitare il concatenamento QuerySet.filter() e QuerySet.exlude(), e utilizzare questo:

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

In attesa della decisione di progettazione. Nel frattempo, l'uso exclude()

L'issue tracker Django ha il notevole entry # 5763 , dal titolo "Queryset non dispone di un '' operatore di filtro" non uguale . È notevole perché (a partire da aprile 2016) è stato "Ha aperto 9 anni fa" (in Django all'età della pietra), "Chiuso 4 anni fa", e "Ultima cambiato 5 mesi fa".

Leggere attraverso la discussione, è interessante. In sostanza, alcune persone sostengono __ne deve essere aggiunto mentre altri dicono exclude() è più libera e quindi __ne dovrebbe non essere aggiunti.

(sono d'accordo con l'ex, perché quest'ultimo argomento è più o meno equivalente a dire Python non dovrebbe avere != perché ha == e not già ...)

Si dovrebbe usare filter e exclude come questo

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

Utilizzando escludere e filtro

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

L'ultimo pezzo di codice esclude tutti gli oggetti dove x! = 5 e 'vero. Prova questo:

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

Ricordate, il segno = nella riga sopra sta assegnando False al parametro a e il numero 5 al parametro x. Non è il controllo per l'uguaglianza. Così, non c'è davvero alcun modo per utilizzare il! = Simbolo in una chiamata di query.

Quello che state cercando sono tutti gli oggetti che hanno o a=false o x=5. In Django, | funge da operatore OR tra i set di query:

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

results = Model.objects.filter(a = True).exclude(x = 5)
Generetes questo sql:
select * from tablex where a != 0 and x !=5
The sql dipende da come il tuo Vero / Falso campo è rappresentata, e il motore di database. Il codice di Django è tutto ciò che serve però.

Django-modello-valori (disclosure: autore) fornisce un'implementazione della NotEqual ricerca, come in questa risposta . Esso fornisce anche il supporto per esso sintattica:

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

Attenzione per un sacco di risposte errate a questa domanda!

La logica di Gerard è corretta, anche se restituirà un elenco piuttosto che un set di query (che potrebbe non importa).

Se avete bisogno di un set di query, utilizzare Q:

from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top