В 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)
Возможно, объекты 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>, ...]
В вашем запросе есть двойной отрицательный результат, вы хотите исключить все строки, где x не 5, поэтому, другими словами, вы хотите включить все строки, где x IS 5. Я считаю, что это будет трюк.
results = Model.objects.filter(x=5).exclude(a=true)
Чтобы ответить на ваш конкретный вопрос, нет "не равного", но, вероятно, из-за того, что у django есть методы "фильтр" и "исключить", поэтому вы всегда можете просто переключить логический раунд, чтобы получить желаемый результат.
results = Model.objects.filter(a=true).exclude(x=5)
Синтаксис 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 как Dave Vogt предлагает и используя filter()
или exclude()
как Джейсон Бейкер предлагает, вы получите именно то, что вам нужно для любого возможного запроса.
tg=Tag.objects.filter(user=request.user).exclude(name__regex=r'^(public|url)$')
и это работает.
Легко создать пользовательский поиск с помощью 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)
В Django 1.9/1.10 есть три варианта.
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)
В то время как с помощью моделей вы можете фильтровать с помощью =
, __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')
Вы должны использовать filter
и exclude
как это
results = Model.objects.exclude(a=true).filter(x=5)
exclude()
Отслеживание проблем Django имеет замечательную запись # 5763, под названием "Queryset не имеет" не равного "оператора фильтра". Это замечательно, потому что (по состоянию на апрель 2016 года) это было "открылся 9 лет назад" (в эпоху эпохи Джанго), "закрыто 4 года назад", и "последний изменен 5 месяцев назад".
Прочитайте обсуждение, это интересно.
В принципе, некоторые люди утверждают, что __ne
следует добавить
в то время как другие говорят, что exclude()
яснее и, следовательно, __ne
не следует добавлять.
(Я согласен с первым, потому что последний аргумент
примерно эквивалентно тому, что Python не должен иметь !=
, потому что
он имеет ==
и not
уже...)
Последний бит кода исключает все объекты, где x!= 5 и a - True. Попробуйте следующее:
results = Model.objects.filter(a=False, x=5)
Помните, что знак = в приведенной выше строке присваивает False параметру a и номер 5 параметру x. Это не проверка равенства. Таким образом, на самом деле нет никакого способа использовать символ!= В вызове запроса.
results = Model.objects.filter(a = True).exclude(x = 5)Генерирует этот sql:
select * from tablex where a != 0 and x !=5sql зависит от того, как представлено ваше поле True/False, и механизм базы данных. Код django - это все, что вам нужно.
То, что вы ищете, это все объекты, имеющие либо a=false
, либо x=5
. В Django |
служит в качестве оператора OR
между запросами:
results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
a=true
а затем применяет фильтрx=5
к остальным. Предполагаемый запрос требует только тех, у которых естьa=true
иx!=5
. Разница в том, что все те, у когоa=true
иx=5
, также отфильтрованы.