Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter gte,lte date on datetime field?

I'm trying to figure out how to filter QuerySet using date extracted from datetime.

I use Django-filter and I can't compose such lookup without iterating over QuerySet which is very uneffective.

I tried datetime__date__gte which doesn't work.

class MyReservationsFilter(FilterSet):
    datetime__lte = DateFilter(method='datetime_filter',name='lte')
    class Meta:
        model = Reservation
        fields = {'status': ['exact'],
                  # 'datetime': ['lte', 'gte'],
                  'destination_from': ['exact'],
                  'destination_to': ['exact'],}


    def datetime_filter(self, queryset, name, value):

        lookup = 'datetime__'+name
        return queryset.filter(**{lookup:value})

Do you know what to do?

I can't use datetime__lte/gte because:

I have a Reservation object r.

>> r.datetime
>> datetime.datetime(2017, 8, 31, 17, 55)
>> r.datetime.date()
>> datetime.date(2017, 8, 31)

So now I try to filter based on date:

Reservation.objects.filter(datetime__lte=datetime.date(2017, 8, 31),datetime__gte=datetime.date(2017, 8, 31))

>> []

It's because it doesn't look only on date but on time too. So I need to extract date to be able to filter properly.

like image 486
Milano Avatar asked Sep 13 '17 09:09

Milano


People also ask

What is __ GTE in Django?

The gte lookup is used to get records that are larger than, or equal to, a specified value. For a greater than, but not or equal to, search, use the gt lookup.

What is Django filter?

Django-filter is a generic, reusable application to alleviate writing some of the more mundane bits of view code. Specifically, it allows users to filter down a queryset based on a model's fields, displaying the form to let them do this.

What is LTE in Python?

gte stands for 'greater than or equal', lte stands for 'lower than or equal' accordingly.


1 Answers

When you want to only compare the date portion of a datetime field, you need to use the date transform. eg,

Reservation.objects.filter(datetime__date__lte=date(2017, 1, 1))

Getting this to work with FilterSets doesn't require a custom method. Filter expressions are constructed by joining the field_name and lookup_expr arguments of the filter constructor. The field_name argument should correspond to the model field name, and the lookup_expr should account for the transform and lookup type.

class MyReservationsFilter(FilterSet):
    datetime__lte = DateFilter(field_name='datetime', lookup_expr='date__lte')

    class Meta:
        model = Reservation
like image 92
Sherpa Avatar answered Sep 23 '22 02:09

Sherpa