首页 文章

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

提问于
浏览
535

在Django模型QuerySets中,我看到有一个 __gt__lt 用于比较值,但是有 __ne / != / <>not equals ?)

我想使用不等于过滤掉:

例:

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)

13 回答

  • 493

    使用模型时,可以使用 =__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')
    
  • 72

    也许Q objects对这个问题有帮助 . 我从来没有使用它们,但似乎它们可以被否定和组合,就像普通的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>, ...]
    
  • 39

    使用排除和过滤

    results = Model.objects.filter(x=5).exclude(a=true)
    
  • 7

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

    Django问题跟踪器具有非凡的entry #5763, Headers 为"Queryset doesn't have a "不等于" filter operator" . 值得注意的是(截至2016年4月)它是"opened 9 years ago"(在Django石器时代),"closed 4 years ago"和"last changed 5 months ago" .

    通读讨论,很有意思 . 基本上,有些人认为应该加上 __ne 而其他人说 exclude() 更清楚,因此不应该添加 __ne .

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

  • 16

    它's easy to create a custom lookup with Django 1.7. There'是Django official documentation中的一个 __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
    

    然后你需要注册它:

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

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

    results = Model.objects.exclude(a=True, x__ne=5)
    
  • 548

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

    from model_values import F
    Model.objects.exclude(F.x != 5, a=True)
    
  • 4

    你应该像这样使用 filterexclude

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

    Generetes this sql:

    select * from tablex where a != 0 and x !=5
    

    sql取决于你的True / False字段的表示方式和数据库引擎 . django代码就是你所需要的 .

  • 8

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

    results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
    
  • 100

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

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

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

  • 3

    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
    

    Django 1.8 中添加了 register_lookup 装饰器并像往常一样启用自定义查找:

    results = Model.objects.exclude(a=True, x__ne=5)
    
  • 13

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

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

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

  • 62

    查询中的 field=value 语法是 field__exact=value 的简写 . 那就是Django puts query operators on query fields in the identifiers . 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 suggests并使用 filter()exclude() 作为Jason Baker suggests,您将获得几乎任何可能的查询所需的内容 .

相关问题