Как сделать не равным в фильтрации запросов Django?
в запросах модели Django я вижу, что есть __gt и __lt для сравнительных значений, но есть ли __ne/!=/<> (не равно?)
Я хочу отфильтровать, используя не равно:
пример:
Model:
bool a;
int x;
Я хочу
results = Model.objects.exclude(a=true, x!=5)
на != неверный синтаксис. Я пытался!--5-->, <>.
Я закончил использование:
results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)
13 ответов
может быть Q объекты может помочь в этой проблеме. Я никогда не использовал их, но, похоже, их можно отрицать и комбинировать, как обычные выражения python.
Update: я только что попробовал, кажется, работает довольно хорошо:
>>> 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 равно 5. Я верю, что это поможет.
results = Model.objects.filter(x=5).exclude(a=true)
чтобы ответить на ваш конкретный вопрос, нет "не равно", но это, вероятно, потому, что django имеет как "фильтр", так и "исключить" методы, доступные, поэтому вы всегда можете просто переключить логический раунд, чтобы получить желаемый результат.
на 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() as Джейсон Бейкер предлагает вы получите именно то, что нужно для любого возможного запроса.
легко создать пользовательский поиск с 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)
на Джанго 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декоратор был добавлен в Джанго 1.8 и включает custom поиск как обычно: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')
в ожидании решения дизайна. Между тем, используйте exclude()
в трекере Django issue tracker есть замечательный запись #5763, под названием "Queryset не имеет" не равного "оператора фильтра". Примечательно, что (в апреле 2016) он был "открыт 9 лет назад "(в каменном веке Джанго), "закрыт 4 года назад", и "последний раз изменена 5 месяцев назад".
прочитайте обсуждение, это интересно.
В принципе, некоторые люди утверждают __ne должны добавлено
в то время как другие говорят exclude() понятнее и, следовательно,__ne
должен!--12-->не быть добавлены.
(Я согласен с первым, потому что последний аргумент
примерно эквивалентно тому, что Python не должен иметь != потому что
он имеет == и not уже...)
последний бит кода исключит все объекты, где x!=5 и a истинно. Попробуйте это:
results = Model.objects.filter(a=False, x=5)
помните, что знак = в приведенной выше строке присваивает False параметру a и число 5 параметру x. Это не проверка на равенство. Таким образом, на самом деле нет никакого способа использовать != символ в вызове запроса.
то, что вы ищете все объекты, которые были либо a=false или x=5. В Джанго,| служит OR оператор между запросами:
results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
Django-model-values (раскрытие: автор) обеспечивает реализацию NotEqual поиск, как и в ответ. Он также обеспечивает синтаксическую поддержку для него:
from model_values import F
Model.objects.exclude(F.x != 5, a=True)
results = Model.objects.filter(a = True).exclude(x = 5)Generetes этот SQL-код:
select * from tablex where a != 0 and x !=5sql зависит от того, как представлено поле True/False и компонент database engine. Код Django-это все, что вам нужно.