1

公式のDjangoドキュメントのクエリセットからの除外に関するセクション(https://docs.djangoproject.com/en/dev/ref/models/querysets/#exclude)には、いくつかのクエリの説明があります。

この例では、pub_dateが2005-1-3より後であり、見出しが「Hello」であるすべてのエントリを除外しています。

Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')

SQL用語では、次のように評価されます。

SELECT ...
WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')

この例では、pub_dateが2005-1-3より後のエントリ、または見出しが「Hello」であるすべてのエントリを除外しています。

Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello')

SQL用語では、次のように評価されます。

SELECT ...
WHERE NOT pub_date > '2005-1-3'
AND NOT headline = 'Hello'

2番目の例はより制限的であることに注意してください。

最後のものは私にはわかりません。最初のものと2番目のものの違いはわかりませんが、誰かがこれを説明できますか?

4

2 に答える 2

2

最初の例ではネストされた部分式を作成し、2番目の例では2つの別個の式を作成します。

于 2013-02-15T12:56:04.450 に答える
1

「2番目の例はより制限的であることに注意してください。」という部分を意味する場合は、おそらくより数学的なアプローチが役立ちます。

NOT (pub_date > '2005-1-3' AND headline = 'Hello')

次のように翻訳できます:

NOT pub_date > '2005-1-3' OR NOT headline = 'Hello'

これと比較して:

NOT pub_date > '2005-1-3' AND NOT headline = 'Hello'

のいずれかの部分をORtrueにする必要があるため、制限が緩和されます。つまり、-A OR Bは制限が緩和されA AND Bます。

ドキュメントに戻ると、最初のケースでは、両方の制限に同時に適合する人を除外します。2番目では、最初の制限に適合する人を除外し、そこから2番目の制限に適合する人を除外します。つまり、いずれかの制限に適合する人を除外します。

@OPのコメント:AA、AB、BB、CCの4つのアイテムがあると想像してください。私たちが言うなら:

Item.objects.filter(name_startswith='A', name_endswith='B')

結果は{AB}になります。当然、私たちが言うなら:

Item.objects.exclude(name_startswith='A', name_endswith='B')

結果は{AA、BB、CC}になります。これは、「A」で始まり「B」で終わるものだけを除外するためです。次のもの:

Item.objects.exclude(name_startswith='A')

結果は{BB、CC}になります。ただし、別の除外をチェーンする場合:

Item.objects.exclude(name_startswith='A').exclude(name_endswith='B')

私たちは実際に言っていますTHE_RESULT_OF_THE_FIRST_EXCLUDE.exclude(name_endswith='B')。あれは:

{BB, CC}.exclude(name_endswith='B')

{CC}を返します。とは異なりfilter

Item.objects.filter(<condition_1>).filter(<condition_2>)

次と同じ結果になります。

Item.objects.filter(<condition_1>, <condition_2>)

除外は連鎖しています。これはブール演算に似ています。

NOT(A AND B)= NOT A OR NOT B NOT(A OR B)= NOT A AND NOT B

于 2013-02-15T13:17:48.340 に答える