Django4 中文入门教程 Django4.0 执行查询-通过Q对象完成复杂查询

2024-02-25 开发教程 Django4 中文入门教程 匿名 4

在类似 ​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))
)