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

时间:2009-07-22 15:22:20

标签: django orm django-q

我希望创建一个稍微复杂一点的查询,使用原始SQL很容易编写。以下是raw中查询的示例:

  

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

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

现在我知道了Q对象,我知道有关过滤但是我似乎无法完全理解如何在Django ORM中实现这一目标。

任何提示?

由于

4 个答案:

答案 0 :(得分:22)

您可以以某种动态的方式继续构建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)

答案 1 :(得分:13)

虽然googletorp是正确的,你不能用字符串动态构造查询,你可以使用字典参数。类似的东西:

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

其中mydict1和2的格式为:

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

答案 2 :(得分: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:
    ...

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

答案 3 :(得分:2)

这是做动态的好方法" OR"查询:

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))