Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter on datetime closest to the given datetime

Tags:

django

I have a model which has a datetime field. Now given a particular datetime - DT, I need to get the object which has the datetime closest to DT. Is this possible?

Thanks,

like image 313
shreyj Avatar asked Apr 06 '13 20:04

shreyj


2 Answers

You can get it with two queries and some logic:

The idea is to find one object immediately following and one immediately preceding the target datetime and to return one of them:

# this method is on the model's manager
def get_closest_to(self, target)
    closest_greater_qs = self.filter(dt__gt=target).order_by('dt')
    closest_less_qs    = self.filter(dt__lt=target).order_by('-dt')

    try:
        try:
            closest_greater = closest_greater_qs[0]
        except IndexError:
            return closest_less_qs[0]

        try:
            closest_less = closest_less_qs[0]
        except IndexError:
            return closest_greater_qs[0]
    except IndexError:
        raise self.model.DoesNotExist("There is no closest object"
                                      " because there are no objects.")

    if closest_greater.dt - target > target - closest_less.dt:
        return closest_less
    else:
        return closest_greater

To get it with one query, you have to drop out of ORM to raw SQL.

like image 58
Pavel Anossov Avatar answered Sep 30 '22 15:09

Pavel Anossov


I'd like to complete Pavel's answer, as:

dt__gte dt__lte

should be used instead.

Filtering when providing the exact date won't work properly otherwise.

like image 37
Lucas Avatar answered Sep 30 '22 15:09

Lucas