Как сделать не равным в фильтрации запросов 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 можно использовать для достижения равного запроса.