michaelT
michaelT

Reputation: 1711

Django: Filter data between to dates | DatetimeField received a naive datetime

I simply want to filter my records between two dates.

Let's say there is a record table Measurements that has the property timestamp:

class Measurements(models.Model):
    id = models.BigAutoField(primary_key=True)
    timestamp = models.DateTimeField()

When I checked the timestamp of the last record Measurements.objects.last().timestamp it returns:

datetime.datetime(2020, 10, 13, 6, 29, 48, 90138, tzinfo=<UTC>)

Now I want to filter the data between to dates from_date and to_date. According to previous questions about this issue, I used make_aware. For testing I used count to get the amount of entries.

from .models import *
from datetime import datetime
from django.utils.timezone import make_aware

def get_measurements(request):
    from_date = make_aware(datetime(2020, 10, 12, 15, 30, 0, 0))
    to_date = make_aware(datetime(2020, 10, 12, 16, 0, 0, 0))
    print(from_date)
    print(to_date)

    measurements = DriveMeasurements.objects.filter(
        plc_timestamp__range=["2020-01-01", "2020-01-31"])
    print(measurements.count())

When printing the two dates in my shell, it returns:

datetime.datetime(2020, 10, 12, 15, 30, tzinfo=<UTC>)
datetime.datetime(2020, 10, 12, 16, 0, tzinfo=<UTC>)

When I run the function above, Django fires the following message:

RuntimeWarning: DateTimeField Measurements.timestamp received a naive datetime (2020-01-31 00:00:00) while time zone support is active. warnings.warn("DateTimeField %s received a naive datetime (%s)"

The print statement print(measurements.count()) prints 0 but there are ~ 18000 records in the database.

So why is the filter not working and the Django message thrown?

Upvotes: 2

Views: 2703

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476584

It is indeed correct that you make the from_date and to_date aware, but you do not use that in the __range check. You should work with:

def get_measurements(request):
    from_date = make_aware(datetime(2020, 10, 12, 15, 30, 0, 0))
    to_date = make_aware(datetime(2020, 10, 12, 16, 0, 0, 0))
    print(from_date)
    print(to_date)

    measurements = DriveMeasurements.objects.filter(
        #  use timezone aware datetimes ↓
        plc_timestamp__range=(from_date, to_date)
    )
    print(measurements.count())

Upvotes: 2

Related Questions