Как мне это сделать не равны по фильтрации объект QuerySet в Django?


в модели Django QuerySets, я вижу, что есть __gt и __lt для сравнительных значений, но есть ли __ne/!=/<> (не равно?)

Я хочу отфильтровать с помощью не равно:

пример:

Model:
    bool a;
    int x;

Я хочу

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

The != неверный синтаксис. Я пытался __ne,<>.

Я в конечном итоге с помощью:

results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)
13 515

13 ответов:

может быть 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 имеет как "фильтр", так и "исключить" доступные методы, поэтому вы всегда можете просто переключить логический раунд, чтобы получить желаемый результат.

the 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)

на Django 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
    

    The 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')

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

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

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

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

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

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

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

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

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

С помощью exclude и filter

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

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

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)
генерирует этот sql:
select * from tablex where a != 0 and x !=5
sql зависит от того, как представлено ваше поле True/False и компонент database engine. Код Django-это все, что вам нужно.