Llanilek
Llanilek

Reputation: 3466

Next upcoming date model object ignoring past dates

I'm trying to utilise latest() on a django model queryset to return the next upcoming date in a model.

I've tried a few different things, using __lte and __gte lookups on a filter and to no avail.

The filter option would work for me, if there was a way to effectively utilise a model method within an exclude() but without writing a custom manager that's not going to be an option.

There must be an easier way?

class RaidSession(models.Model):
    scheduled = models.DateTimeField()
    duration = models.DurationField()

    def is_expired(self):
        duration_to_date = self.scheduled + self.duration
        return True if duration_to_date < timezone.now() else False

Upvotes: 0

Views: 30

Answers (1)

dhke
dhke

Reputation: 15388

Since I'm a little old school, it usually helps me to think of such problems as an SQL query. In your case this would be

SELECT * FROM app_raidsession rs
    WHERE rs.scheduled >= now()
    ORDER BY rs.scheduled
    LIMIT 1

This gives you the next scheduled raid.

In django ORM, you should be able to translate this more or less straightforward to:

from django.utils.timezone import now

# first() returns None if the result is empty
next_raid = models.RaidSession.objects \
    .filter(scheduled__gte=now()) \
    .order_by('scheduled') \
    .first()

If the duration is relevant, you will need an F-expression:

from django.db.models import F

next_raid = models.RaidSession.objects \
    .filter(scheduled__gte=now() - F('duration')) \
    .order_by('scheduled') \
    .first()

Upvotes: 1

Related Questions