使用 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 查询的主要内容,如果未能解决你的问题,请参考以下文章