Django Objects Filter received a naive datetime while time zone support is active when using min max range

Question:

So this question is specifically about querying a timezone aware date range with max min in Django 4.2.

Timezone is set as TIME_ZONE = ‘UTC’ in settings.py and the model in question has two fields:

open_to_readers = models.DateTimeField(auto_now=False, verbose_name="Campaign Opens")
close_to_readers = models.DateTimeField(auto_now=False, verbose_name="Campaign Closes")

The query looks like

allcampaigns = Campaigns.objects.filter(open_to_readers__lte=today_min, close_to_readers__gt=today_max)

Failed Solution 1

    today_min = datetime.combine(timezone.now().date(), datetime.today().time().min)
    today_max = datetime.combine(timezone.now().date(), datetime.today().time().max)
    print("Today Min", today_min, " & Today Max", today_max)

returns the following which would be a suitable date range except it also gives the error below for both min and max.

Today Min 2023-10-21 00:00:00  & Today Max 2023-10-21 23:59:59.999999

DateTimeField ... received a naive datetime (9999-12-31 23:59:59.999999) while time zone support is active.

Partial Working Solution

today_min = timezone.now()
allcampaigns = Campaigns.objects.filter(open_to_readers__lte=today_min, close_to_readers__gt=today_min)

Returns results without error but the time given is the current time and not the minimum or maximum for the day.

Failed Solution 2 from here:

    now = datetime.now(timezone.get_default_timezone())
    today_min = now.min
    today_max = now.max
    print("Today Min", today_min, " & Today Max", today_max)

Returns Today Min 0001-01-01 00:00:00 & Today Max 9999-12-31 23:59:59.999999 and the aforementioned timezone error.

How can I create two timezone aware datetime for the minumum and maximum parts of the day?

Asked By: Byte Insight

||

Answers:

Likely the easiest way is just:

from datetime import timedelta

from django.utils.timezone import now

date_min = now().replace(hour=0, minute=0, second=0, microsecond=0)
date_max = date_min + timedelta(days=1) - date_min.resolution
Campaigns.objects.filter(
    open_to_readers__lte=today_min, close_to_readers__gt=today_min
)
Answered By: Willem Van Onsem

You can use make_aware

from datetime import datetime
from django.utils import timezone

current_date = timezone.now().date()
today_min = timezone.make_aware(datetime.combine(current_date, datetime.min.time()))
today_max = timezone.make_aware(datetime.combine(current_date, datetime.max.time()))

print('Today Min', today_min)
print('Today Max', today_max)
Answered By: Yuri R
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.