838

在 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)
4

16 回答 16

918

您可以为此使用Q 对象。它们可以用~运算符取反,并像普通的 Python 表达式一样组合:

from myapp.models import Entry
from django.db.models import Q

Entry.objects.filter(~Q(id=3))

将返回除3ID 为以下的所有条目:

[<Entry: Entry object>, <Entry: Entry object>, <Entry: Entry object>, ...]
于 2009-07-20T17:58:38.883 回答
733

您的查询似乎有一个双重否定,您想要排除所有x不是 5 的行,所以换句话说,您想要包括所有x 5 的行。我相信这会成功:

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

要回答您的具体问题,没有“不等于”字段查找,但这可能是因为 Django 具有可用的filterexclude方法,因此您始终可以切换逻辑以获得所需的结果。

于 2010-11-09T23:56:13.523 回答
150

查询中的field=value语法是field__exact=value. 也就是说Django 将查询运算符放在了 identifiers 中的查询字段上。Django 支持以下运算符:

exact
iexact
contains
icontains
in
gt
gte
lt
lte
startswith
istartswith
endswith
iendswith
range

date
year
iso_year
month
day
week
week_day
iso_week_day
quarter
time
hour
minute
second

isnull
regex
iregex

我敢肯定,通过将这些与Dave Vogt 建议的 Q 对象结合使用,filter()或者exclude()按照Jason Baker 的建议,您将获得几乎任何可能查询所需的内容。

于 2009-07-20T18:07:02.423 回答
131

有三个选项:

  1. excludefilter

    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. 注册自定义查找函数

    from django.db.models import Lookup
    from django.db.models 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
    

    哪个可以照常使用:

    results = Model.objects.exclude(a=True, x__ne=5)
    
于 2016-02-24T13:12:47.010 回答
114

创建自定义查找很容易,Django 的官方文档__ne中有一个查找示例。

您需要先创建查找本身:

from django.db.models import 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

然后你需要注册它:

from django.db.models import Field
Field.register_lookup(NotEqual)

现在您可以__ne像这样在查询中使用查找:

results = Model.objects.exclude(a=True, x__ne=5)
于 2015-03-24T08:07:27.437 回答
48

=虽然您可以使用、__gt__gte__lt、过滤模型__lte,但您不能使用ne!=。但是,您可以使用 Q 对象实现更好的过滤。

您可以避免链接QuerySet.filter()and QuerySet.exclude(),并使用它:

from django.db.models import Q
object_list = QuerySet.filter(~Q(field='not wanted'), field='wanted')
于 2011-01-18T14:34:16.470 回答
27

待定的设计决定。同时,使用exclude()

Django 问题跟踪器有一个非凡的条目 #5763,标题为"Queryset doesn't have a "not equal" filter operator"。这很了不起,因为(截至 2016 年 4 月)它是“9 年前开放的”(在 Django 石器时代)、“4 年前关闭”和“5 个月前最后一次更改”。

通读讨论,很有趣。基本上,有些人认为__ne应该添加,而另一些人则认为exclude()更清楚,因此__ne 应该添加。

(我同意前者,因为后者的论点大致相当于说 Python 不应该有!=,因为它有==并且not已经......)

于 2016-04-21T08:44:38.413 回答
25

使用排除和过滤

results = Model.objects.filter(x=5).exclude(a=true)
于 2018-07-12T10:43:14.147 回答
16

你应该使用filter并且exclude喜欢这个

results = Model.objects.exclude(a=true).filter(x=5)
于 2015-09-25T08:52:02.660 回答
8

Django-model-values(披露:作者)提供了NotEqual查找的实现,如this answer中所示。它还为其提供语法支持:

from model_values import F
Model.objects.exclude(F.x != 5, a=True)
于 2018-01-13T03:23:37.900 回答
8

这将给出您想要的结果。

from django.db.models import Q
results = Model.objects.exclude(Q(a=True) & ~Q(x=5))

对于不相等,您可以~在相等查询中使用。显然,Q可以用来达到相等查询。

于 2019-09-29T10:48:09.593 回答
7

最后一段代码将排除 x!=5 且 a 为 True 的所有对象。试试这个:

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

请记住,上一行中的 = 符号将 False 分配给参数 a,将数字 5 分配给参数 x。它不是检查平等。因此,实际上没有任何方法可以在查询调用中使用 != 符号。

于 2009-03-26T19:54:05.923 回答
7

您正在寻找的是所有具有a=false x=5的对象。在 Django 中,|充当OR查询集之间的运算符:

results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
于 2016-06-27T12:50:58.053 回答
7

结果 = Model.objects.filter(a = True).exclude(x = 5)
生成此 sql:
select * from tablex where a != 0 and x !=5
sql 取决于您的 True/False 字段的表示方式以及数据库引擎。django 代码就是你所需要的。

于 2017-02-22T12:12:00.773 回答
2

注意这个问题的许多错误答案!

Gerard 的逻辑是正确的,尽管它会返回一个列表而不是一个查询集(这可能无关紧要)。

如果您需要查询集,请使用 Q:

from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))
于 2019-03-14T13:21:43.090 回答
1

如果我们需要根据我们可以使用的子查询集排除/否定,

条件过滤器

当条件表达式返回一个布尔值时,可以直接在过滤器中使用它。这里non_unique_account_type返回一个布尔值。但是,我们仍然可以在过滤器中使用它。

>>> non_unique_account_type = Client.objects.filter(
...     account_type=OuterRef('account_type'),
... ).exclude(pk=OuterRef('pk')).values('pk')
>>> Client.objects.filter(~Exists(non_unique_account_type))

在 SQL 术语中,它的计算结果为:

SELECT * FROM client c0
WHERE NOT EXISTS (
  SELECT c1.id
  FROM client c1
  WHERE c1.account_type = c0.account_type AND NOT c1.id = c0.id
)
于 2021-06-13T21:03:51.407 回答