クエリセットでの空またはNULL名のフィルタリング


463

私が持っているfirst_namelast_namealias私が検索する必要があります(オプション)。したがって、エイリアスセットを持つすべての名前を取得するクエリが必要です。

私ができる場合のみ:

Name.objects.filter(alias!="")

では、上記と同等のものは何ですか?

回答:


840

あなたはこれを行うことができます:

Name.objects.exclude(alias__isnull=True)

null値空の文字列を除外する必要がある場合は、次のように条件を連結することをお勧めします。

Name.objects.exclude(alias__isnull=True).exclude(alias__exact='')

これらのメソッドを一緒にチェーンすると、基本的に各条件が個別にチェックされます。上記の例でaliasは、がnull または空の文字列の行を除外するため、null でもNameでもないaliasフィールドを持つすべてのオブジェクトを取得できます。生成されたSQLは次のようになります。

SELECT * FROM Name WHERE alias IS NOT NULL AND alias != ""

への1回の呼び出しに複数の引数を渡すこともできexcludeます。これにより、すべての条件を満たすオブジェクトのみが確実に除外されます。

Name.objects.exclude(some_field=True, other_field=True)

ここでは、some_field other_field trueの行が除外されるため、両方のフィールドがtrueではないすべての行が取得されます。生成されたSQLコードは次のようになります。

SELECT * FROM Name WHERE NOT (some_field = TRUE AND other_field = TRUE)

または、ロジックがそれよりも複雑な場合は、DjangoのQオブジェクトを使用できます

from django.db.models import Q
Name.objects.exclude(Q(alias__isnull=True) | Q(alias__exact=''))

詳細については、このページとDjangoドキュメントのこのページを参照してください

余談ですが、私のSQLの例は類推にすぎません。実際に生成されたSQLコードはおそらく異なって見えます。Djangoクエリが生成するSQLを実際に確認することで、Djangoクエリがどのように機能するかをより深く理解できます。


5
あなたの編集は間違っていると思います:チェーンフィルターはSQLを自動的に作成せORず(この場合のみ)、SQLを生成しますAND。このページを参照してください:docs.djangoproject.com/en/dev/topics/db/queries/…チェーンの利点は、複雑なクエリ条件を混合excludefilterてモデル化できることです。実際のSQLをモデル化するOR場合は、Django Qオブジェクトを使用する必要があります:docs.djangoproject.com/en/dev/topics/db/queries/… 編集内容を編集してこれを反映してください。 。
シェジ2013年

1
@shezi:私はそれを類推としてもっと意味しました-実際のSQLコードがOR条件を融合するためにを使用することが保証されることを意味していませんでした。明確にするために回答を編集します。
サーシャチェディゴフ2013年

1
このロジックを表すにはさまざまな方法があることに注意してください。たとえば、NOT (A AND B)はと同等NOT A OR NOT Bです。SQLを知っているがORMに慣れていない新しいDjango開発者を混乱させるものだと思います。
サーシャチェディゴフ2013年

3
私はドモーガンの法則を知っています。これが私の要点です。あなたの例ANDは、最初のクエリのをに変換するORことを利用するためにのみ機能しますexclude。一般的なケースでは、チェーンをTHEN、つまりと考える方がおそらく正しいでしょうexclude(A) THEN exclude(B)。上記の過酷な言語については申し訳ありません。あなたの答えは本当に良いですが、私は新しい開発者があなたの答えをあまりにも一般的に受け入れるのを心配しています。
シェジ2013

2
@shezi:十分に公正です。私はそれがDjangoの用語ではなくSQLの観点で考えて良いでしょうことに同意し、私はちょうど提示の面で連鎖することを考えANDORSQLの背景からジャンゴに来て誰かのために役に立つかもしれません。Djangoをより深く理解するために、ドキュメントは私よりも優れていると思います。
サーシャチェディゴフ2013

49
Name.objects.filter(alias__gt='',alias__isnull=False)

2
よくわかりませんが、alias__isnull=False条件は冗長だと思います。フィールドがNull確かにある場合、最初の句によって除外されますか?
2015年

私の以前のコメント/質問は別として、私はここでの肯定的な論理は他のいくつかの回答よりも従うのが簡単だと思います。
Bobble

@Bobbleはデータベースの実装に依存します- 順序付けは
wpercy

alias__gt私のようなJSONから空の文字列を除外したいJSON型の列のために働いていただけのものでした{'something:''}。だから、作業構文は次のとおりです。jsoncolumnname__something__gt=''
bartgras

38

まず、Djangoのドキュメントでは、CharFieldやTextFieldなどの文字列ベースのフィールドにNULL値を使用しないことを強く推奨しています。説明については、ドキュメントをご覧ください。

https://docs.djangoproject.com/en/dev/ref/models/fields/#null

解決策:QuerySetsのメソッドをチェーンすることもできます。これを試して:

Name.objects.exclude(alias__isnull=True).exclude(alias="")

それはあなたが探しているセットをあなたに与えるはずです。


5

Django 1.8から、

from django.db.models.functions import Length

Name.objects.annotate(alias_length=Length('alias')).filter(alias_length__gt=0)

5
これは「できること」のようであり、やるべきことではありません。2つの単純なチェックに比べてクエリの複雑さが大幅に改善されます。
Oli 2017

3

を使用するときによくある間違いを避けるために、次の点に注意してくださいexclude

のようにexclude()ブロックに複数の条件を追加することはできません。複数の条件を除外するには、複数のexclude()を使用する必要がありますfilter

不正

User.objects.filter(email='example@example.com ')。exclude(profile__nick_name =' '、profile__avt =' ')

正解

User.objects.filter(email='example@example.com ')。exclude(profile__nick_name =' ')。exclude(profile__avt =' ')


0

あなたは単にこれを行うことができます:

Name.objects.exclude(alias="").exclude(alias=None)

それは本当にそれほど単純です。 filter一致するために使用されexclude、それが指定するもの以外すべてに一致します。これはSQLとして評価されますNOT alias='' AND alias IS NOT NULL


これは誤りです。質問は、クエリから空(alias="")およびNULL(alias=None)エイリアスを除外することを目的としています。あなたのインスタンスにはが含まれますName(alias=None)
damon

@damon-私は.filter(alias!="")、タイトルではなく同等のものに答えていました。回答を編集しました。ただし、文字フィールドはNULL値を許可してはならず、非値には空の文字列を使用する必要があります(規則に従って)。
Tim Tisdall

-1

これは、別の簡単な方法です。

Name.objects.exclude(alias=None)

Noneと同じではありません""
Tim Tisdall
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.