Как мне выполнить фильтрацию not equal в наборе запросов Django?

StackOverflow https://stackoverflow.com/questions/687295

Вопрос

В наборах запросов модели Django я вижу, что есть __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 РАВНО 5.Я верю, что это сработает.

results = Model.objects.filter(x=5).exclude(a=true)

Чтобы ответить на ваш конкретный вопрос, нет "не равно", но это, вероятно, потому, что в django доступны как методы "filter", так и "exclude", так что вы всегда можете просто переключить логический цикл, чтобы получить желаемый результат.

в 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() как Джейсон Бейкер предлагает вы получите именно то, что вам нужно практически для любого возможного запроса.

С помощью 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 есть три варианта.

  1. Цепочка exclude и filter

    results = Model.objects.exclude(a=true).filter(x=5)
    
  2. Использование Q() Объекты и тот ~ оператор

    from django.db.models import Q
    object_list = QuerySet.filter(~Q(a=True), x=5)
    
  3. Зарегистрировать a пользовательская функция поиска

    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 и включает пользовательский поиск как обычно:

    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 обладает замечательными запись №5763, под названием "В наборе запросов нет оператора фильтра "не равно"".Это примечательно, потому что (по состоянию на апрель 2016 года) это было "открыто 9 лет назад" (в каменном веке Джанго), "закрыто 4 года назад" и "последнее изменение 5 месяцев назад".

Прочтите обсуждение, это интересно.В принципе, некоторые люди спорят __ne следует добавить в то время как другие говорят exclude() яснее и, следовательно, __ne следует не быть добавленным.

(Я согласен с первым, потому что последний аргумент примерно эквивалентен высказыванию, что Python не должен иметь != потому что это имеет == и not уже...)

Вы должны использовать filter и exclude вот так

results = Model.objects.exclude(a=true).filter(x=5)

Использование исключения и фильтрации

results = Model.objects.filter(x=5).exclude(a=true)

Последний бит кода исключит все объекты, где x!=5 и a равно True.Попробуй это:

results = Model.objects.filter(a=False, x=5)

Помните, что знак = в приведенной выше строке присваивает параметру a значение False, а параметру x - число 5.Это не проверка на равенство.Таким образом, на самом деле нет никакого способа использовать символ != в вызове запроса.

То, что вы ищете, - это все объекты, которые имеют либо a=false или x=5.В Джанго, | служит в качестве OR оператор между наборами запросов:

results = Model.objects.filter(a=false)|Model.objects.filter(x=5)

results = Model.objects.filter(a = True).exclude(x = 5)
Генерирует этот sql:
select * from tablex where a != 0 and x !=5
sql зависит от того, как представлено ваше поле True / False, и от компонента database engine.Однако код django - это все, что вам нужно.

Django-модель-значения (раскрытие:автор) обеспечивает реализацию Не равный поиск, как в этот ответ.Он также предоставляет для него синтаксическую поддержку:

from model_values import F
Model.objects.exclude(F.x != 5, a=True)

Следите за множеством неправильных ответов на этот вопрос!

Логика Джерарда верна, хотя она вернет список, а не набор запросов (что может не иметь значения).

Если вам нужен набор запросов, используйте Q:

from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top