我怎么做不等于在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中有三个选项。

  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. 注册一个自定义的查找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)