4

我正在寻找使用原始 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 中干净地实现这一点。

有小费吗?

谢谢

4

4 回答 4

25

您可以以某种动态的方式继续构建您的 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)
于 2009-07-23T18:19:10.233 回答
15

尽管 googletorp 是正确的,您不能使用字符串动态构造查询,但您可以使用字典参数来完成。就像是:

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

其中 mydict1 和 2 的形式为:

{'field1': 'value1'}
{'field2__icontains': 'value2'}

等等

于 2009-07-22T18:27:27.600 回答
2

像这样的东西应该工作:

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:
    ...

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

于 2009-07-22T15:42:37.470 回答
2

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

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))
于 2017-01-13T17:28:25.393 回答