筛选对象或(如果找到0的话)按一个数据库命中获取Django中的所有对象

时间:2019-05-09 19:03:51

标签: django django-queryset

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

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

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

我已经检查了子查询,Q,条件表达式,但仍然看不到如何将其适合一个查询。

2 个答案:

答案 0 :(得分:1)

好吧,就像我所拒绝的一样(我仍然认为这是过早的优化),好奇心使我变得更好。这虽然不漂亮,但是可以解决问题:

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)

尝试过,绝对只有一个查询。有趣的是,对于大型数据集,它实际上是否确实要快得多……

答案 1 :(得分:0)

您最好的选择是使用.exists(),否则您的代码就可以了

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