便利(?)なQオブジェクトを使った検索

最近Djangoに触れている:-)常山です。

を見ていて面白い使い方があったので試してみました。

前回のアプリを使います。
データーには"Mac"を含んだ文字列は存在するが、"windows"を含んだ文字列は存在しない状態です。

>>>from myproject.weblog.models import Entry
>>>from django.db.models import Q
>>>query = None
>>>q = Q(**{"title__icontains": "windows"})

qの中身がどうなっているか見てみます。

>>>q.__dict__

{'children': [('title__icontains', 'windows')],
 'connector': 'AND',
 'negated': False,
 'subtree_parents': []}

これが基本です。
ANDとORを試すのにもう一つオブジェクトを作ります。

>>a = Q(**{"title__icontains": "mac"})
>>a.__dict__

{'children': [('title__icontains', 'mac')],
 'connector': 'AND',
 'negated': False,
 'subtree_parents': []}

まずはANDを試してみます。

>>>z = a & q
>>>z.__dict__

{'children': [('title__icontains', 'mac'), ('title__icontains', 'windows')],
 'connector': 'AND',
 'negated': False,
 'subtree_parents': []}

つぎにOR

>>>y = a | q
>>>y.__dict__

{'children': [('title__icontains', 'mac'), ('title__icontains', 'windows')],
 'connector': 'OR',
 'negated': False,
 'subtree_parents': []}

connectorの値が'OR'に変更されています。
それぞれのオブジェクトを元にEntryモデルの検索を行ってみます。

>>>Entry.objects.filter(z)
[]

>>>Entry.objects.filter(y)
[<Entry: Mac>]

これを利用すると検索する対象フィールドを選択して検索したりすることができます。