如何在 Django 查询集过滤中执行不等于?
-
22-08-2019 - |
题
在 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)
解决方案
也许 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>, ...]
其他提示
您的查询似乎具有双重负数,您想排除所有行不在5的行,因此换句话说,您想在其中包含所有行,其中x为5。我相信这将有能力解决问题。
results = Model.objects.filter(x=5).exclude(a=true)
为了回答您的特定问题,没有“不等于”,但这可能是因为Django既具有“滤镜”和“排除”方法,因此您始终可以切换逻辑回合以获得所需的结果。
这 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对象结合在一起 戴夫·沃格特(Dave Vogt)建议 并使用 filter()
或者 exclude()
作为 杰森·贝克(Jason Baker)建议 几乎所有可能的查询,您将完全获得所需的内容。
使用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 有三个选择。
-
results = Model.objects.exclude(a=true).filter(x=5)
-
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)
在使用模型时,您可以过滤 =
, __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年4月)它是“ 9年前开业”(在Django Stone Age中),“ 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为tur。尝试这个:
results = Model.objects.filter(a=False, x=5)
请记住,上行中的=符号将false分配给参数A,而参数x的数字5分配给了。它没有检查平等。因此,实际上没有任何方法可以在查询调用中使用!=符号。
您正在寻找的是所有的对象 a=false
或者 x=5
. 。在Django, |
作为 OR
QuerySet之间的操作员:
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 !=5SQL取决于您的真实/错误字段的表示以及数据库引擎。 django代码是您所需的。
注意这个问题的许多错误答案!
Gerard的逻辑是正确的,尽管它将返回列表而不是QuerySet(这可能没关系)。
如果您需要QuerySet,请使用Q:
from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))