Django4.0 执行查询-通过Q对象完成复杂查询
在类似 filter()
中,查询使用的关键字参数是通过"AND"
连接起来的。如果你要执行更复杂的查询(例如,由 OR
语句连接的查询),你可以使用 Q
对象。
Q
对象(django.db.models.Q)
是一个用于封装关键字参数集合的对象。
例如,这个 Q
对象封装了一个 LIKE
查询:
from django.db.models import Q
Q(question__startswith='What')
Q
对象能通过 & 和 |
操作符连接起来。当操作符被用于两个 Q
对象之间时会生成一个新的 Q
对象。
例如,该语句生成一个 Q
对象,表示两个 "question_startswith"
查询语句之间的 "OR"
关系:
Q(question__startswith='Who') | Q(question__startswith='What')
这等价于以下 SQL WHERE
语句:
WHERE question LIKE 'Who%' OR question LIKE 'What%'
你能通过 &
和 |
操作符和括号分组,组合任意复杂度的语句。当然, Q
对象也可通过 ~
操作符反转,允许在组合查询中组合普通查询或反向 (NOT)
查询:
Q(question__startswith='Who') | ~Q(pub_date__year=2005)
每个接受关键字参数的查询函数 (例如 filter()
, exclude()
, get()
) 也同时接受一个或多个 Q
对象作为未命名的参数。若你为查询函数提供了多个 Q
对象参数,这些参数会通过 "AND"
连接。例如:
Poll.objects.get(
Q(question__startswith='Who'),
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)
等价于以下 SQL语句:
SELECT * from polls WHERE question LIKE 'Who%'
AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
查询函数能混合使用 Q
对象和关键字参数。所有提供给查询函数的参数(即关键字参数或 Q
对象)均通过 "AND"
连接。然而,若提供了 Q
对象,那么它必须位于所有关键字参数之前。例如:
Poll.objects.get(
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
question__startswith='Who',
)
相当于前面的例子,但这是无效的:
# INVALID QUERY
Poll.objects.get(
question__startswith='Who',
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)