使用 filter() 和 Q 对象混合的 Django ORM 查询

Posted

技术标签:

【中文标题】使用 filter() 和 Q 对象混合的 Django ORM 查询【英文标题】:A Django ORM query using a mix of filter() and Q objects 【发布时间】:2010-11-13 01:23:05 【问题描述】:

我正在寻找使用原始 SQL 相当容易编写的稍微复杂的查询。这是原始查询的示例:

SELECT my,fields FROM sales WHERE is_paid = False OR status = 'toship' AND otherfield = 'FOO' AND anotherfield = 'BAR'

这很简单,它生成 is_paid = False 的所有结果,然后为我的 AND 匹配生成第二个结果集。

现在我了解了 Q 对象,我了解了过滤,但我似乎不知道如何在 Django ORM 中干净利落地实现这一点。

有什么建议吗?

谢谢

【问题讨论】:

【参考方案1】:

您可以继续以某种动态的方式构建您的 Q 对象。

例子:

query1 = Q(is_paid=False)

query2 = Q()

if status:
    query2 = Q(status=status)

if otherfield:
    query2 = query2 & Q(otherfield=otherfield)

if anotherfield:
    query2 = query2 & Q(anotherfield=anotherfield)

query = query1 | query2

result = model.objects.filter(query)

【讨论】:

【参考方案2】:

虽然 googletorp 是正确的,您不能使用字符串动态构造查询,但您可以使用字典参数来做到这一点。比如:

model.objects.filter(Q(**mydict1) | Q(**mydict2))

mydict1 和 2 的格式为:

'field1': 'value1'
'field2__icontains': 'value2'

等等

【讨论】:

【参考方案3】:

这样的事情应该可以工作:

model.objects.filter(Q(is_paid=False) | Q(status='toship', otherfield='FOO', anotherfield='BAR'))

编辑: 您不能像构造包含要在完成时执行的 SQL 语句的字符串那样动态地创建查询。如果你想这样做,我建议使用 if 状态、函数或最适合你的用例:

if query == 'simple':
    result = model.objects.filter(Q(is_paid=False))
else:
    result = model.objects.filter(Q(is_paid=False) | Q(status='toship', otherfield='FOO', anotherfield='BAR'))
for items in result:
    ...

这可能更复杂,但我相信你明白了。

【讨论】:

好的,我想我的问题是现在。假设我有一个基本上是这样的查询: model.objects.filter(Q(is_paid=False)) 我想用一些动态值向该查询添加另一个 Q 对象,以产生与您发布的查询基本相同的查询,但是它会被动态创建。这就是我在这种情况下苦苦挣扎的地方。我将如何实现这一目标? 别忘了 from django.db.models import Q【参考方案4】:

这是进行动态“或”查询的好方法:

import operator
from django.db.models import Q
from your_app.models import your_model_object

q_list = [Q(question__startswith='Who'), Q(question__startswith='What')]
your_model_object.objects.filter(reduce(operator.or_, q_list))

如果你想使用“AND”:

your_model_object.objects.filter(reduce(operator.and_, q_list))

【讨论】:

以上是关于使用 filter() 和 Q 对象混合的 Django ORM 查询的主要内容,如果未能解决你的问题,请参考以下文章

Q对象

Objects 多条件 Q对象金额F 对象

F对象Q对象聚合函数

F 和 Q 对象

如何在ListAPIView中使用django-filter对过滤结果进行排序

使用带有变量的 Q 对象