python - update - order_by




如何在Django queryset過濾中做到不相等? (8)

在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)

待定設計決策。 同時,使用exclude()

Django問題跟踪器具有顯著的 條目#5763 ,標題為“Queryset沒有”不等於“過濾器運算符” 。 這是值得注意的,因為(截至2016年4月)“9年前開放”(在Django石器時代),“4年前關閉”和“5個月前最後更改”。

通讀討論,這很有趣。 基本上,有些人認為__ne應該被添加,而另一些人則認為exclude()更清晰,因此__ne不應該被添加。

(我同意前者,因為後者的說法大致相當於說Python不應該有!=因為它有==而且not ......)


也許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>, ...]

你正在尋找的是所有具有a=false x=5 。 在Django中, | 在查詢集之間充當OR運算符:

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

你的查詢似乎有一個雙重否定的,你想排除其中x不是5的所有行,換句話說,你想包括所有的行,其中x是5.我相信這將做到這一點。

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

為了回答你的具體問題,沒有“不等於”,但這可能是因為django同時具有“過濾器”和“排除”方法,所以你總是可以切換邏輯來獲得所需的結果。


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

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. 註冊一個自定義查找功能

    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)
    

最後一位代碼將排除x!= 5和a為真的所有對象。 嘗試這個:

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

請記住,上面一行中的=符號將False分配給參數a,數字5分配給參數x。 這不是檢查平等。 因此,在查詢調用中沒有任何方法使用!=符號。


查詢中的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-queryset