Jeremy Swinarton
Jeremy Swinarton

Reputation: 537

Django QuerySet: filter by date, then select one more

Suppose I have a set of Model objects, each one tagged with a date and time. I'd like to select all of the items with a date in the past, plus the one that's closest to today, but in the future. So far, I've got this:

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

This seems clunky. I wonder if there's a way to do this that only hits the database once, using one (clean) QuerySet. Is this possible?

Upvotes: 0

Views: 427

Answers (1)

karthikr
karthikr

Reputation: 99660

You probably would not be able to do it with one database call, as there is no way to know what the next date would be ahead of time, unless you do some preprocessing.

One way is:

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

OR

qs = list(archive, next)

Another approach involving a quick lookup would be

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

Upvotes: 1

Related Questions