0

How can you achieve this with one query:

upcoming_events = Event.objects.order_by('date').filter(date__gte=today)
try:
    return upcoming_events[0]
except IndexError:
    return Event.objects.all().order_by('-date')[0]

My idea is to do something like this:

Event.objects.filter(Q(date__gte=today) | Q(date is max date))[0]

But I don't know how to implement the max date. Maybe I've just to do it with Func. Or When or Case in django.db.expressions might be helpful.

yofee
  • 1,287
  • 12
  • 25

1 Answers1

0

Here is a solution with one query (thanks to this post) but I'm not sure if it's faster than the implementation in my question:

from django.db.models import Max, Value, Q

latest = (
    Event.objects
         .all()
         .annotate(common=Value(1))
         .values('common')
         .annotate(latest=Max('date'))
         .values('latest')
)
events = Event.objects.order_by('date').filter(
    Q(date__gte=datetime.date.today()) | Q(date=latest)
)
return events[0]

In my case I finally just took the rows in question (the two latest) and checked for the right event on Python level.

yofee
  • 1,287
  • 12
  • 25