【问题标题】:Django QuerySet: filter by date, then select one moreDjango QuerySet:按日期过滤,然后再选择一个
【发布时间】:2013-07-12 21:56:52
【问题描述】:

假设我有一组模型对象,每个对象都标有日期和时间。我想选择日期在过去的所有项目,加上最接近今天但在未来的项目。到目前为止,我得到了这个:

from django.utils.timezone import now
from models import Resource

next = Resource.objects.filter(date__gt=now()).reverse()[0]
archive = Resource.objects.filter(date__lt=now())

这看起来很笨重。我想知道是否有一种方法可以使用一个(干净的)QuerySet 只访问数据库一次。这可能吗?

【问题讨论】:

  • 不会有两个查询,因为两种情况相互矛盾。
  • 顺便说一下,next 对于变量来说是个糟糕的选择。是内置next的名称。
  • 很高兴知道。谢谢!

标签: python django django-queryset


【解决方案1】:

您可能无法通过一次数据库调用来完成此操作,因为无法提前知道下一个 date 会是什么,除非您进行一些预处理。

一种方法是:

next = Resource.objects.filter(date__gt=now()).order_by('date')[:1]
archive = Resource.objects.filter(date__lt=now())
qs = list(chain(archive, next))

qs = list(archive, next)

另一种涉及快速查找的方法是

dt = None
now = now()

next = Resource.objects.filter(date__gt=now()).order_by('date')[:1]
if next.exists(): #A quick lookup for the date
    now = next[0].date

archive = Resource.objects.filter(date__lt=now).order_by('date')

【讨论】:

  • 发问者想从单个查询中获取单个查询集,该查询命中 db 一次。
  • @AamirAdnan,很确定只有一个数据库访问权限(正如 OP 所写的那样),这就是 [0][:1] 所在的位置。 QuerySets are lazy.
  • @MathieuMarques 在list(chain(archive, next))archivenext 中会单独评估,因此需要2 个数据库调用
  • @AamirAdnan 刚刚编辑。你能想出更好的方法吗?
  • @karthikr 我的意思是这不能在单个数据库调用中完成。 OP 想单独完成。 :)
猜你喜欢
  • 2016-07-21
  • 2011-03-05
  • 1970-01-01
  • 2017-06-09
  • 2019-03-01
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多