如何在Django查询集过滤中做不相等的操作?

Mik*_*keN 608 python django django-models django-queryset

在Django模型QuerySets中,我看到有一个__gt__ltfor的比较值,但是有__ne/ !=/ <>(不等于?)

我想用不等于过滤掉:

例:

Model:
    bool a;
    int x;
Run Code Online (Sandbox Code Playgroud)

我想要

results = Model.objects.exclude(a=true, x!=5)
Run Code Online (Sandbox Code Playgroud)

!=不正确的语法.我试过__ne,<>.

我最终使用:

results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)
Run Code Online (Sandbox Code Playgroud)

Dav*_*ogt 637

也许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>, ...]
Run Code Online (Sandbox Code Playgroud)

  • @JCLeitão:另请参阅[@ d4nt的答案](http://stackoverflow.com/a/4139956/20578)以获得更直观的语法. (14认同)
  • 是否有任何理由执行“Entry.objects.filter(~Q(id=3))”而不是“Entry.objects.exclude(id=3)”? (12认同)
  • @BobWhitelock:这只是问题的一个简单片段。在现实世界中,很多情况我们都必须使用它。例如:EXCLUDE(A=1 且 B__not=2); 使用额外的 .exclude 是不对的。 (3认同)
  • 我认为它的使用取决于场景,但 Q 对象允许更复杂的查询。例如,您也可以将“~Q”查询与其他查询串在一起。https://docs.djangoproject.com/en/3.2/topics/db/queries/#complex-lookups-with-q-objects (2认同)

d4n*_*4nt 564

您的查询似乎有一个双重否定,您想要排除x不是5的所有行,所以换句话说,您想要包含x IS 5的所有行.我相信这样做会有所帮助.

results = Model.objects.filter(x=5).exclude(a=true)
Run Code Online (Sandbox Code Playgroud)

要回答你的具体问题,没有"不等于",但这可能是因为django同时具有"过滤"和"排除"方法,因此你可以随时切换逻辑轮以获得所需的结果.

  • @danigosa这似乎不对.我自己试过这个,而`exclude`和`filter`调用的顺序没有任何有意义的区别.`WHERE`子句中条件的顺序发生了变化,但这又如何重要? (4认同)
  • @danigosa排除和过滤顺序无关紧要. (4认同)
  • @d4nt:我可能错了,但我认为查询应该是`results = Model.objects.filter(a=true).exclude(x=5)` (2认同)
  • 我认为这是错误的,因为错误地排除了一个实例(x = 4,a = false). (2认同)

Sin*_*ion 120

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
Run Code Online (Sandbox Code Playgroud)

我确信通过将这些与Q对象结合起来,正如Dave Vogt建议和使用的那样,filter()或者exclude()正如Jason Baker建议你将得到你所需要的几乎任何可能的查询.

  • “包含”,“ iexact”等中的“ i”表示“忽略大小写”。它不是用于“逆”。 (2认同)

Dmi*_*lov 91

使用Django 1.7创建自定义查找很容易.Django官方文档中有一个__ne查找示例.

您需要首先创建查找本身:

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
Run Code Online (Sandbox Code Playgroud)

然后你需要注册它:

from django.db.models.fields import Field
Field.register_lookup(NotEqual)
Run Code Online (Sandbox Code Playgroud)

现在您可以在__ne查询中使用查找,如下所示:

results = Model.objects.exclude(a=True, x__ne=5)
Run Code Online (Sandbox Code Playgroud)


ils*_*005 82

Django 1.9/1.10中有三个选项.

  1. 连锁excludefilter

    results = Model.objects.exclude(a=true).filter(x=5)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用Q()对象~运算符

    from django.db.models import Q
    object_list = QuerySet.filter(~Q(a=True), x=5)
    
    Run Code Online (Sandbox Code Playgroud)
  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
    
    Run Code Online (Sandbox Code Playgroud)

    register_lookup在加装饰的Django 1.8和可定制的查找和往常一样:

    results = Model.objects.exclude(a=True, x__ne=5)
    
    Run Code Online (Sandbox Code Playgroud)

  • 想知道 1 与 2 是否存在性能差异 (2认同)

Dam*_*ami 40

虽然与模型,您可以用过滤=,__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')
Run Code Online (Sandbox Code Playgroud)


Lut*_*elt 21

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

Django问题跟踪器有一个非凡的条目#5763,标题为"Queryset没有"不等于"过滤器运算符".值得注意的是(截至2016年4月)它是​​"9年前开放"(在Django石器时代),"4年前关闭","5个月前最后一次改变".

仔细阅读讨论,很有意思.基本上,一些人认为__ne应该有的则说加入exclude()更清晰,因此__ne 应该添加.

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

  • 这不是一个悬而未决的设计决定,他们八年前就决定不这样做。 (3认同)

out*_*ime 15

你应该使用filterexclude喜欢这个

results = Model.objects.exclude(a=true).filter(x=5)
Run Code Online (Sandbox Code Playgroud)

  • 这与你 5 年前的[@d4nt 的答案](/sf/answers/289796951/) 有什么不同? (2认同)

jin*_*iam 15

使用排除和过滤

results = Model.objects.filter(x=5).exclude(a=true)
Run Code Online (Sandbox Code Playgroud)

  • 这与[@d4nt的答案](/sf/answers/289796951/)在你之前8年留下的和[@outoftime的答案](/sf/answers/2294484041/)在3年前做出的有什么不同这个? (3认同)

Jas*_*ker 8

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

results = Model.objects.filter(a=False, x=5)
Run Code Online (Sandbox Code Playgroud)

请记住,上面一行中的=符号是为参数a赋值False,为参数x赋值5.它不是在检查是否平等.因此,在查询调用中实际上没有任何方法可以使用!=符号.

  • 这不是100%相同的事情,因为这些字段也可能有Null值. (3认同)
  • `results = Model.objects.filter(a__in=[False,None],x=5)` (3认同)

Mil*_* Kh 8

这将给出您想要的结果。

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

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


A. *_*ady 7

Django-model-values(公开:作者)提供了NotEqual查找的实现,如此答案所示。它还为此提供了语法支持:

from model_values import F
Model.objects.exclude(F.x != 5, a=True)
Run Code Online (Sandbox Code Playgroud)


小智 7

这应该有效

results = Model.objects.filter(x=5).exclude(a=True)
Run Code Online (Sandbox Code Playgroud)


Ger*_*ard 6

你所寻找的是具有或者所有对象a=false x=5.在Django中,|作为查询集OR之间的运算符:

results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
Run Code Online (Sandbox Code Playgroud)


小智 6

结果= Model.objects.filter(a = True).exclude(x = 5)
生成此sql:
从tablex中选择*,其中a = 0且x!= 5
sql取决于您的True / False字段的表示方式以及数据库引擎。Django代码是您所需要的。