Как сделать не равным в фильтрации запросов Django?
В Django-модели QuerySets я вижу, что для сравнительных значений есть __gt
и __lt
, но есть ли __ne
/!=
/<>
( не равно?)
Я хочу отфильтровать с помощью не равно:
Пример:
Model:
bool a;
int x;
Я хочу
results = Model.objects.exclude(a=true, x!=5)
!=
- неправильный синтаксис. Я пробовал __ne
, <>
.
В итоге я использовал:
results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)
Ответы
Ответ 1
Возможно, объекты Q могут помочь этой проблеме. Я никогда не использовал их, но кажется, что они могут быть сведены на нет и объединены так же, как и обычные выражения python.
Обновление: я просто попробовал, кажется, работает очень хорошо:
>>> 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>, ...]
Ответ 2
В вашем запросе есть двойной отрицательный результат, вы хотите исключить все строки, где x не 5, поэтому, другими словами, вы хотите включить все строки, где x IS 5. Я считаю, что это будет трюк.
results = Model.objects.filter(x=5).exclude(a=true)
Чтобы ответить на ваш конкретный вопрос, нет "не равного", но, вероятно, из-за того, что у django есть методы "фильтр" и "исключить", поэтому вы всегда можете просто переключить логический раунд, чтобы получить желаемый результат.
Ответ 3
синтаксис field=value
в запросах является сокращением для field__exact=value
. То есть Django помещает операторы запросов в поля запросов в идентификаторах. Django поддерживает следующие операторы:
exact
iexact
contains
icontains
in
gt
gte
lt
lte
startswith
istartswith
endswith
iendswith
range
year
month
day
week_day
isnull
search
regex
iregex
Я уверен, что, комбинируя их с объектами Q, как Дейв Фогт предлагает, и используя filter()
или exclude()
, как Джейсон Бейкер предлагает, вы получите именно то, что вы нужно практически для любого возможного запроса.
Ответ 4
Легко создать пользовательский поиск с помощью Django 1.7. Там __ne
пример поиска в официальной документации Django.
Сначала нужно создать поиск:
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
Затем вам необходимо зарегистрировать его:
from django.db.models.fields import Field
Field.register_lookup(NotEqual)
И теперь вы можете использовать поиск __ne
в ваших запросах следующим образом:
results = Model.objects.exclude(a=True, x__ne=5)
Ответ 5
В Django 1.9/1.10 есть три варианта.
-
Цепочка exclude
и filter
results = Model.objects.exclude(a=true).filter(x=5)
-
Используйте Q()
объекты и ~
оператор
from django.db.models import Q
object_list = QuerySet.filter(~Q(a=True), x=5)
-
Зарегистрируйте пользовательскую функцию поиска
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
Декоратор register_lookup
был добавлен в Django 1.8 и
позволяет выполнять обычную проверку, как обычно:
results = Model.objects.exclude(a=True, x__ne=5)
Ответ 6
В то время как с помощью моделей вы можете фильтровать с помощью =
, __gt
, __gte
, __lt
, __lte
, вы не можете использовать ne
, !=
или <>
. Тем не менее, вы можете добиться лучшей фильтрации при использовании объекта Q.
Вы можете избежать цепочки QuerySet.filter()
и QuerySet.exlude()
и использовать это:
from django.db.models import Q
object_list = QuerySet.filter(~Q(field='not wanted'), field='wanted')
Ответ 7
Ожидаемое дизайнерское решение. Между тем, используйте exclude()
Отслеживание проблем Django имеет замечательную запись # 5763,
под названием "Queryset не имеет" не равного "оператора фильтра".
Это замечательно, потому что (по состоянию на апрель 2016 года) это было
"открылся 9 лет назад" (в эпоху эпохи Джанго),
"закрыто 4 года назад", и
"последний изменен 5 месяцев назад".
Прочитайте обсуждение, это интересно.
В принципе, некоторые люди утверждают, что __ne
следует добавить
в то время как другие говорят, что exclude()
яснее и, следовательно, __ne
не следует добавлять.
(Я согласен с первым, потому что последний аргумент
примерно эквивалентно тому, что Python не должен иметь !=
, потому что
он имеет ==
и not
уже...)
Ответ 8
Вы должны использовать filter
и exclude
как это
results = Model.objects.exclude(a=true).filter(x=5)
Ответ 9
Использование exclude и filter
results = Model.objects.filter(x=5).exclude(a=true)
Ответ 10
Последний бит кода исключает все объекты, где x!= 5 и a - True. Попробуйте следующее:
results = Model.objects.filter(a=False, x=5)
Помните, что знак = в приведенной выше строке присваивает False параметру a и номер 5 параметру x. Это не проверка равенства. Таким образом, на самом деле нет никакого способа использовать символ!= В вызове запроса.
Ответ 11
Django-model-values (раскрытие: автор) обеспечивает реализацию поиска NotEqual, как в этом ответе. Он также обеспечивает синтаксическую поддержку:
from model_values import F
Model.objects.exclude(F.x != 5, a=True)
Ответ 12
То, что вы ищете, это все объекты, имеющие либо a=false
, либо x=5
. В Django |
служит в качестве оператора OR
между запросами:
results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
Ответ 13
results = Model.objects.filter(a = True).exclude(x = 5)
Генерирует этот sql: select * from tablex where a != 0 and x !=5
sql зависит от того, как представлено ваше поле True/False, и механизм базы данных. Код django - это все, что вам нужно.
Ответ 14
Остерегайтесь множества неправильных ответов на этот вопрос!
Логика Джерарда верна, хотя она возвращает список, а не набор запросов (что может не иметь значения).
Если вам нужен набор запросов, используйте Q:
from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))
Ответ 15
Это даст желаемый результат.
from django.db.models import Q
results = Model.objects.exclude(Q(a=True) & ~Q(x=5))
для не равных вы можете использовать ~
для одинакового запроса. очевидно, что Q
можно использовать для достижения равного запроса.