How to filter django queryset based on hours range?

Question:

class MyModelSerializer(serailizers.ModelSerializer):
        hour = serializers.SerializerMethodField()

        def get_hour(self, obj):
           created_at = obj.created_at # datetime
           now = datetime.now()
           return (now - datetime).total_seconds() // 3600
         
        class Meta:
           model = MyModel
           fields = "__all__"

In the api there are 3 static filter parameters:

  1. filter list upto 3 hr
  2. filter list between 3 to 12hr
  3. filter list above 12 hr

How can I filter below api based on the hour that has been calulated in the above serializer ?

For example if I filter by upto3 then the list should return all the objects having hr less or equal to 3.

The below way returns if the hours matches the exact value only.

 @api_view(["GET"])
 def get_list(request):
     qs = MyModel.objects.all()
     hr = request.GET.get("hr")
     if hr:
         hr = int(hr)
         frm = now() - timedelta(hours=hr+1)
         to = now() - timedelta(hours=hr)
         qs = qs.filter(created_at__range=(frm, to))
         return MyModelSerializer(qs, many=True).data 

EDIT:

I want a filter like this .

     upto_3h = request.GET.get("upto_3hr", False)
     if upto_3h:
         # filter which has hour less or equal to 3h
     between_3_to_12 = request.GET.get("between_3_to_12", False)
     if between_3_to_12:
         # filter accordingly

     above_12 = request.GET.get("above_12", False)
     if above_12:
         # filter accordingly
           
Asked By: Mark

||

Answers:

You can filter with:

from datetime import timedelta
from django.db.models.functions import Now

if request.GET.get('upto_3hr'):
    qs = qs.filter(created_at__gte=Now()-timedelta(hours=3))
elif request.GET.get('between_3_to_12'):
    qs = qs.filter(created_at__range=(
        Now()-timedelta(hours=12), Now()-timedelta(hours=3))
    )
elif request.GET.get('above_12'):
    qs = qs.filter(created_at__lte=Now()-timedelta(hours=12))
# …
Answered By: Willem Van Onsem