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

发布于 2024-07-27 21:34:16 字数 353 浏览 7 评论 0原文

我希望创建一个稍微复杂的查询,使用原始 SQL 可以相当轻松地编写该查询。 以下是原始查询的示例:

从销售中选择我的字段,其中 is_paid = False OR status = 'toship' AND otherfield = 'FOO' AND anotherfield = 'BAR'

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

现在我了解了 Q 对象,了解了过滤,但我似乎无法完全理解如何在 Django ORM 中干净地实现这一点。

有小费吗?

谢谢

I'm looking to create a slightly more complex query that is written fairly easily using raw SQL. Here's an example of the query in raw:

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

This is simple, it generates all the results that are is_paid = False and then a second result set for my AND matches.

Now I know about Q objects, I know about filtering but I can't seem to wrap my mind around how to achieve this in the Django ORM cleanly.

Any tips?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

颜漓半夏 2024-08-03 21:34:16

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

You can keep building your Q object in a somewhat dynamic fashion.

Example:

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)
べ繥欢鉨o。 2024-08-03 21:34:16

尽管 googletorp 是正确的,您不能使用字符串动态构造查询,但您可以使用字典参数来实现。 类似于:

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

其中 mydict1 和 2 的形式为:

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

等等。

Although googletorp is right that you can't construct the query dynamically with a string, you can do it with dictionary parameters. Something like:

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

where mydict1 and 2 are of the form:

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

etc.

北方的韩爷 2024-08-03 21:34:16

这是进行动态“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))

This is a great way to do dynamic "OR" querying:

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

if you want to use "AND":

your_model_object.objects.filter(reduce(operator.and_, q_list))
兔小萌 2024-08-03 21:34:16

像这样的事情应该有效:

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

这可能更复杂,但我相信你明白这个想法。

Something like this should work:

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

Edit:
You can't create the query dynamically the same way you can construct a string containing a SQL statement to be executed when completed. If you want to do this, I would suggest using an if state, function or what suits your use case best:

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

This could be more complex, but I'm sure you get the idea.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文