DjangoでQ()オブジェクトを使用する

2363 ワード

問題は一般的にDjangoプログラムでデータベースを検索する操作はQuerySetで行われます.例えば、次のコードです.
>>> q1 = Entry.objects.filter(headline__startswith="What")
>>> q2 = q1.exclude(pub_date__gte=datetime.date.today())
>>> q3 = q1.filter(pub_date__gte=datetime.date.today())

または、次のように組み合わせます.
>>>q1 = Entry.objects.filter(headline_startswith="What").exclude(pub_date_gte=datetime.date.today())

私たちのプログラムがますます複雑になるにつれて、クエリーの条件も複雑になります.このように簡単にfilter()を通じてクエリーを行う条件は、クエリーがますます長くなります.
Q()オブジェクトは,これらの条件を組み合わせるためである.クエリーの条件に条件を組み合わせる必要がある場合(たとえば、2つの条件「および」または「または」)です.Q()を使用してオブジェクトをクエリーできます.例えば次のコード
fromdjango.db.modelsimports Q
q=Q(question_startswith="What")

これによりQ()オブジェクトが生成され,シンボル&または|を用いて複数のQ()オブジェクトを組み合わせてfilter(),exclude(),get()などの関数に渡すことができる.複数のQ()オブジェクトを組み合わせると、Djangoは自動的に新しいQ()を生成します.たとえば、次のコードは2つの条件を1つに組み合わせます.
Q(question__startswith='Who') | Q(question__startswith='What')

SQL文を使用して、上記のコードを理解します.
WHEREquestionLIKE 'Who%' ORquestionLIKE 'What%'

Q()オブジェクトの前に文字「~」を使用して、意味「非」を表すことができます.例えば、次のコードです.
Q(question__startswith='Who') | ~Q(pub_date__year=2005)

対応するSQL文は次のように理解できます.
WHEREquestionlike "Who%" ORyear(pub_date) !=2005

これにより、「&」または「|」およびカッコを使用して条件をグループ化し、より複雑なクエリーロジックに組み合わせることができます.
クエリ関数に複数のQ()オブジェクトを渡すこともできます.たとえば、次のコードがあります.
News.objects.get(
    Q(question__startswith='Who'),
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)

複数のQ()オブジェクト間の関係Djangoは、自動的に「かつ(and)」関係として理解される.SQL文を使用して上記のコードを理解すると、次のようになります.
SELECT * fromnewsWHEREquestionLIKE 'Who%'  AND (pub_date = '2005-05-02' ORpub_date = '2005-05-06')

Q()オブジェクトはキーワードパラメータとともにクエリー関数に渡すことができますが、Q()オブジェクトをキーワードパラメータの前に置いて、次のコードを見てください
正しいやり方
News.objects.get(
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
    question__startswith='Who')

誤ったやり方で,コードはキーワードパラメータをQ()オブジェクトの前に置く.
News.objects.get(
    question__startswith='Who',
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))