web-dev-qa-db-ja.com

Djangoのクエリセットフィルタリングで等しくないのはどうやってやるのですか?

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)
562
MikeN

多分 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>, ...]
587
Dave Vogt

あなたのクエリは二重の否定をしているように見えます、あなたはxが5でないすべての行を除外したいです、言い換えればあなたはx IS 5のすべての行を含めたいです。

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

あなたの具体的な質問に答えるために、「等しくない」はありませんが、それはおそらくDjangoが利用可能な "filter"と "exclude"メソッドの両方を持っているからです。

515
d4nt

クエリの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 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

それからあなたはそれを登録する必要があります:

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

そして今、あなたはこのようにあなたのクエリで__neルックアップを使うことができます:

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

Django 1.9/1.10 には3つの選択肢があります。

  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)
    
74
ilse2005

モデルでは、=__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')
39
Dami

保留中の設計決定。その間、exclude()を使用します

Django課題トラッカーには、注目すべき エントリ#576 、タイトル付き "Querysetには「等しくない」フィルタ演算子がありません」。 (2016年4月現在)「9年前に開かれた」(Django石器時代)、「4年前に閉じられた」、「5か月前に最後に変更された」ため、注目に値します。

議論を読んで、それは興味深いです。基本的に、一部の人は__neを追加すべきだと主張し、他の人はexclude()がより明確であるため、__nenotを追加すべきだと主張します。

(前者には同意します。後者の引数はPythonには!=notがすでにあるため、==を含めるべきではないということとほぼ同じです。)

21
Lutz Prechelt

このようにfilterexcludeを使うべきです

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

除外とフィルタの使用

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

コードの最後のビットは、x!= 5でaがTrueのすべてのオブジェクトを除外します。これを試して:

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

上の行の=記号は、パラメータaにFalseを、パラメータxに5を割り当てることを忘れないでください。平等をチェックしていません。したがって、クエリ呼び出しで!=記号を使用する方法は実際にはありません。

8
Jason Baker

あなたが探しているものはa=false または x=5を持つすべてのオブジェクトです。 Djangoでは、|はクエリセット間でOR演算子として機能します。

results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
5
Gerard
results = Model.objects.filter(a = True).exclude(x = 5)
tablexから*を選択します。a!= 0、x!= 5です。
4
M. Dasn

Django-model-values (開示:作者)は この答え のように、 NotEqual lookupの実装を提供します。また、それに対する構文サポートも提供します。

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

この質問に対する多くの間違った答えに気をつけてください!

Gerardの論理は正しいのですが、クエリセットではなくリストを返します(これは問題ではないかもしれません)。

クエリセットが必要な場合は、Qを使用してください。

from Django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))
0
Mark Bailey