it-roy-ru.com

Как мне сделать неравное в 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)
571
MikeN

Возможно объекты 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>, ...]
594
Dave Vogt

Похоже, ваш запрос имеет двойной минус, вы хотите исключить все строки, где x не равно 5, то есть, другими словами, вы хотите включить все строки, где x IS 5. Я считаю, что это поможет.

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

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

523
d4nt

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

111
SingleNegationElimination

Создать собственный поиск легко с помощью 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)
85
Dmitrii Mikhailov

В Django 1.9/1.10 есть три варианта.

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

    results = Model.objects.exclude(a=true).filter(x=5)
    
  2. Используйте Q() objects и оператор ~

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

    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)
    
76
ilse2005

При использовании моделей вы можете фильтровать с помощью =, __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')
39
Dami

В ожидании проектного решения. Тем временем используйте exclude()

Система отслеживания проблем Django имеет замечательное entry # 576 , под названием "Queryset не имеет оператора фильтра" не равно "" . Это примечательно тем, что (по состоянию на апрель 2016 года) он был "открыт 9 лет назад" (в каменном веке Django), "закрыт 4 года назад" и "последний изменился 5 месяцев назад".

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

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

18
Lutz Prechelt

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

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

Использование exclude и filter

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

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

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

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

8
Jason Baker

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

results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
5
Gerard
results = Model.objects.filter (a = True) .exclude (x = 5)
выберите * из таблицы где a! = 0 и x! = 5
5
M. Dasn

Django-model-values (раскрытие: автор) обеспечивает реализацию поиска NotEqual , как в этот ответ . Это также обеспечивает синтаксическую поддержку для этого:

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

Остерегайтесь множества неправильных ответов на этот вопрос!

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

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

from Django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))
0
Mark Bailey