在filter()
,exclude()
等当中,如果有多个关键字参数,那他们在SQL的查询逻辑中是AND
的关系。现实中有时候我们查询的逻辑并不是简单的A字段=某值,B字段__startwith=某值
,如果我们要使用OR
等的逻辑,就要使用Q对象
。
Q 对象
可以使用 &
、|
和 ^
运算符组合。当在两个 Q 对象
上使用运算符时,它会产生一个新的 Q 对象
。此外,可以使用 ~
运算符对 Q 对象
进行取反。
每个接受关键字参数的查询函数 (例如 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)),
)