Explain Codes LogoExplain Codes Logo

How do I filter query objects by date range in Django?

python
date-range-filtering
django-utilities
datetime-objects
Anton ShumikhinbyAnton Shumikhin·Dec 16, 2024
TLDR

For swift date range filtering in Django, slap __range into your .filter(). Marvel at the concise code:

from myapp.models import MyModel from datetime import date # I've got a date with Django, at range! queryset = MyModel.objects.filter(date_field__range=(date(2023, 1, 1), date(2023, 1, 31)))

Here, replace MyModel and date_field with your model and date column names respectively.

Picking apart date range filtering

Every date’s a mystery waiting to be unsolved. Let's dissect Django date range filtering, one piece at a time.

Let's not forget the ends

Include and exclude the end date in your range, don't let it feel left out:

from datetime import timedelta # Inclusive dating; the more, the merrier queryset = MyModel.objects.filter(date_field__gte=date(2023, 1, 1), date_field__lte=date(2023, 1, 31) + timedelta(days=1)) # Exclusive dating; sometimes, less is more queryset = MyModel.objects.filter(date_field__gte=date(2023, 1, 1), date_field__lt=date(2023, 1, 31))

Yearly and monthly escapades

Laser focus on specific months or years by using __year and __month:

# Time-travel to see what January 2023 looks like queryset = MyModel.objects.filter(date_field__year=2023, date_field__month=1)

Time waits for no field

Dealing with DateTimeField? Ensure you account for the time too:

from datetime import datetime, time start_datetime = datetime.combine(date(2023, 1, 1), time.min) # Start of the day, rise and shine! end_datetime = datetime.combine(date(2023, 1, 31), time.max) # End of the day, lights out! queryset = MyModel.objects.filter(date_field__range=(start_datetime, end_datetime))

Keep those variable names meaningful and Django-grammar-checker happy with the right syntax.

Cementing our filtering prowess

Handling time zones like a boss

Your field data might not always come from your time zone. No worries, Django's utilities got you covered:

from django.utils import timezone now = timezone.now() yesterday = now - timedelta(days=1) # Who's a time traveler now? queryset = MyModel.objects.filter(date_field__range=(yesterday, now))

Some sage advice on date range querying

  • __range lookup: Because who doesn't love clear syntax?
  • Be consistent with dates and datetimes to keep confusion at bay.
  • Your end date is no wallflower, remember to include or exclude it with gte/lte or gt/lt.
  • The time matters if you're using datetime fields. Don't let it sneak up on you!