我怎么做不等于在Django queryset过滤?
在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对象可以帮助解决这个问题。 我从来没有使用过它们,但它似乎可以被否定和组合,就像正常的Pythonexpression式一样。
更新:我只是试了一下,似乎工作得很好:
>>> 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 Vogtbuild议并使用filter()
或者exclude()
一样, Jason Bakerbuild议你可以准确地得到你需要的任何可能的查询。
使用Django 1.7创build自定义查找很容易。 Django官方文档中有一个__ne
查找示例。
您需要首先创build查找:
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中有三个选项。
-
链
exclude
和filter
results = Model.objects.exclude(a=true).filter(x=5)
-
使用
Q()
对象和~
运算符from django.db.models import Q object_list = QuerySet.filter(~Q(a=True), x=5)
-
注册一个自定义的查找function
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
在Django 1.8中添加了
register_lookup
修饰器,并像往常一样启用自定义查找: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')
你应该使用filter
并像这样exclude
results = Model.objects.exclude(a=true).filter(x=5)
等待devise决定。 同时,使用exclude()
Django问题跟踪器具有显着的条目#5763 ,标题为“Queryset没有”不等于“filter运算符” 。 (截至2016年4月)“9年前开放”(在Django石器时代),“4年前closures”,“5个月前更新”是显着的。
通读讨论,很有意思。 基本上,有些人认为__ne
应该被添加,而另一些人则认为exclude()
更清晰,因此__ne
不应该被添加。
(我同意前者,因为后者的说法大致相当于说Python不应该有!=
因为它已经==
而且not
…)
代码的最后一位将排除x!= 5和a为真的所有对象。 尝试这个:
results = Model.objects.filter(a=False, x=5)
请记住,上面一行中的=符号将False赋值给参数a,将数字5赋值给参数x。 这不是检查平等。 因此,在查询调用中没有任何方法使用!=符号。
results = Model.objects.filter(a = True).exclude(x = 5)
Generetes这个SQL:
从tablex中select*,其中!= 0和x!= 5
SQL取决于你的True / False字段是如何表示的,还有数据库引擎。 Django代码是你所需要的。
你正在寻找的是所有具有a=false
或 x=5
。 在Django中, |
作为查询集之间的OR
运算符:
results = Model.objects.filter(a=false)|Model.objects.filter(x=5)