过滤对象或(如果找到0)通过一次数据库命中获取Django中的所有对象

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (38)

在Django中有一种方法可以在一次数据库命中中实现以下功能(调试工具栏显示2个查询)吗?

q = SomeModel.objects.filter(name=name).order_by(some_field)
if q.count() == 0:
    q = SomeModel.objects.all().order_by(some_field)

我想检查是否有具有给定名称的对象。如果是,则返回它们。如果不是,则返回所有对象。全部在一个查询中完成。

我检查了Subquery,Q,条件表达式,但仍然没有看到如何将它放入一个查询中。

提问于
用户回答回答于

好吧,就像我抵制一样(我仍然认为这是不成熟的优化),好奇心让我变得更好。这不是很好但是诀窍:

from django.db.models import Q, Exists

name_qset = SomeObject.objects.filter(name=name)
q_func = Q(name_exists=True, name=name) | Q(name_exists=False)
q = SomeModel.objects.annotate(
    name_exists=Exists(name_qset)
).filter(q_func).order_by(some_field)

尝试了它,绝对只有一个查询。有趣的是看大型数据集实际上是否明显更快......

用户回答回答于

你最好的选择是使用.exists(),否则你的代码很好

q = SomeModel.objects.filter(name=name).order_by(some_field)
if not q.exists():
    q = SomeModel.objects.all().order_by(some_field)

扫码关注云+社区

领取腾讯云代金券