11

I am trying to filter Matches scheduled in a certain day. I can't just do this:

match_queryset.filter(start=date)

because it also filters by time, but I can do this:

match_queryset.filter(start__year=a_date.year, start__month=a_date.month, start__day=a_date.day)

But this is too complex, I feel like there could be a simpler way.

Then I can also use a range:

t0 = datetime.datetime.combine(a_date, datetime.time(0, 0))
t1 = datetime.datetime.combine(a_date, datetime.time(23, 59, 59))
match_queryset.filter(start__gte=t0, start__lte=t1)

But this just seems to be an overkill and it probably generates an inefficient query.

Can't I just make a query to target the actual date? Something like:

# this of course doesn't work
match_queryset.filter(start__date=date)

No need to say I have tried looking for solution and could not find any.

dabadaba
  • 9,064
  • 21
  • 85
  • 155

2 Answers2

21

From Django 1.9 you can use the __date field lookup, exactly as you have mentioned in your question. For older versions, you will have to do with the other methods.

e.g.

Entry.objects.filter(start__date=datetime.date(2005, 1, 1))
Entry.objects.filter(start__date__gt=datetime.date(2005, 1, 1))
shad0w_wa1k3r
  • 12,955
  • 8
  • 67
  • 90
2

If you can't use the __date filter, I think the cleanest way would be to do this:

from datetime import datetime, timedelta

d = datetime.now()  # or whatever you want

match_queryset.filter(start__gte=d.date(), start__lt=d.date()+timedelta(days=1))

If you have USE_TZ=True in Django's settings.py, you will get warnings:

RuntimeWarning: DateTimeField (...) received a naive datetime (...) while time zone support is active.

but the filter will still work. The comparison will be made in Django's timezone (TIME_ZONE from settings.py), at least that's what I'm getting.

raszek
  • 21
  • 2