Django クエリセット フィルタリングで不等号を実行するにはどうすればよいですか?
-
22-08-2019 - |
質問
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オブジェクト この問題の解決に役立つかもしれません。私はこれらを使用したことがありませんが、通常の 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>, ...]
他のヒント
クエリには二重否定があるようです。x が 5 でないすべての行を除外したい、つまり、x が 5 であるすべての行を含めたいと考えています。これでうまくいくと思います。
results = Model.objects.filter(x=5).exclude(a=true)
あなたの特定の質問に答えるために、「等しくない」はありませんが、これはおそらく、django には「filter」メソッドと「exclude」メソッドの両方が利用可能であるため、いつでもロジックラウンドを切り替えるだけで目的の結果を得ることができます。
の 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 オブジェクトと組み合わせれば、次のように確信できます。 デイブ・フォークト氏が提案する そして使用して filter()
または exclude()
として ジェイソン・ベイカーが提案する ほぼすべてのクエリに対して必要なものが正確に得られます。
Django 1.7 ではカスタム ルックアップを簡単に作成できます。あるよ __ne
の検索例 Django 公式ドキュメント.
最初にルックアップ自体を作成する必要があります。
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)
で ジャンゴ 1.9/1.10 3つの選択肢があります。
-
results = Model.objects.exclude(a=true).filter(x=5)
使用
Q()
オブジェクト そしてその~
オペレーター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
の
register_lookup
デコレータが追加されました ジャンゴ 1.8 そして、通常どおりカスタムルックアップを有効にします: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')
デザイン決定待ち。その間、使用 exclude()
Django 問題トラッカーには注目すべき機能があります。 エントリー #5763、タイトル 「クエリセットには「等しくない」フィルター演算子がありません」。(2016年4月の時点で)(9年前にオープンした」(Django Stone Age)、「4年前に閉鎖」、「5か月前に最後に変化した」という点で驚くべきことです。
議論を読んでみてください、興味深いです。基本的に、議論する人もいます __ne
他の人が言う間に追加する必要があります exclude()
より明確なので、 __ne
すべき ない 追加される。
(私は前者に同意します。なぜなら、後者の議論はPythonが持ってはいけないと言うこととほぼ同等であるからです !=
持っているからです ==
そして not
すでに...)
使用する必要があります filter
そして exclude
このような
results = Model.objects.exclude(a=true).filter(x=5)
除外とフィルターの使用
results = Model.objects.filter(x=5).exclude(a=true)
コードの最後の部分では、x!=5 および a が True であるすべてのオブジェクトを除外します。これを試して:
results = Model.objects.filter(a=False, x=5)
上の行の = 記号はパラメータ a に False を割り当て、パラメータ x に数値 5 を割り当てていることに注意してください。平等性をチェックしているわけではありません。したがって、クエリ呼び出しで != 記号を使用する方法は実際にはありません。
探しているのは、次のいずれかを持つすべてのオブジェクトです。 a=false
または x=5
. 。ジャンゴでは、 |
として機能します OR
クエリセット間の演算子:
results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
results = Model.objects.filter(a = True).exclude(x = 5)次の SQL を生成します。
select * from tablex where a != 0 and x !=5SQL は、True/False フィールドの表現方法とデータベース エンジンによって異なります。ただし、必要なのは django コードだけです。
Django モデルの値 (開示:著者) の実装を提供します。 等しくない ルックアップ、次のように この答え. 。また、その構文サポートも提供します。
from model_values import F
Model.objects.exclude(F.x != 5, a=True)
この質問に対する不正確な回答が多数あるので注意してください。
Gerard のロジックは正しいですが、クエリセットではなくリストを返します (これは重要ではないかもしれません)。
クエリセットが必要な場合は、Q を使用します。
from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))