Come faccio a fare una non uguale a Django filtraggio set di query?
-
22-08-2019 - |
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)
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.
-
results = Model.objects.exclude(a=true).filter(x=5)
-
from django.db.models import Q object_list = QuerySet.filter(~Q(a=True), x=5)
-
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 !=5The 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))