4

I'm using Django 2.2

In my application, timezone support is enabled by USE_TZ=True in the settings file.

I have models with DateTime field created.

I need to filter data based on the date. The date can be provided by the user or else it will be default to now().

This is what I'm doing

from datetime import datetime, timedelta
from django.utils import timezone

class Generator:

    def __init__(self, start_date=None, end_date=None):

        if end_date:
            self.end_date = datetime.strptime(end_date, '%Y-%m-%d').date()
        else:
            self.end_date = timezone.now().date()

        if start_date:
            self.start_date = datetime.strptime(start_date, '%Y-%m-%d').date()
        else:
            self.start_date = self.end_date - timedelta(days=7)

    def get_query(self, d):

        query = MyModel.objects.filter(
            d__in=d,
            created__gte=start_date,
            created__lte=end_date
        )

        return query

But this is giving error

RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2020-02-28 00:00:00) while time zone support is active.

How can I get this issue solved?

Anuj TBE
  • 9,198
  • 27
  • 136
  • 285
  • Does this answer your question? [RuntimeWarning: DateTimeField received a naive datetime](https://stackoverflow.com/questions/18622007/runtimewarning-datetimefield-received-a-naive-datetime) – UrbanConor Mar 08 '23 at 10:19

3 Answers3

4

When time zone support is enabled, the database layer expects to receive only aware datetimes from your code. This warning occurs when it receives a naive datetime. This indicates that you haven’t finished porting your code for time zone support. check documentation.

You need to change naive datetime to your project timezone datetime by using make_aware() function. For that you have to update your code like below.

from datetime import datetime, timedelta
from django.utils import timezone

class Generator:

    def get_mytimezone_date(original_datetime):
        new_datetime = datetime.strptime(original_datetime, '%Y-%m-%d')
        tz = timezone.get_current_timezone()
        timzone_datetime = timezone.make_aware(new_datetime, tz, True)
        return timzone_datetime.date()

    def __init__(self, start_date=None, end_date=None):

        if end_date:
            self.end_date = self.get_mytimezone_date(end_date)
        else:
            self.end_date = timezone.now().date()

        if start_date:
            self.start_date = self.get_mytimezone_date(start_date)
        else:
            self.start_date = self.end_date - timedelta(days=7)

    def get_query(self, d):

        query = MyModel.objects.filter(
            d__in=d,
            created__gte=start_date,
            created__lte=end_date
        )

        return query

I hope this will help you :)

PyMaster
  • 1,094
  • 7
  • 11
3

You can add the following code to ensure the start_date and end_date having timezone info. E.g.

tz = timezone.get_current_timezone()

start_date = start_date.replace(tzinfo=tz)
end_date = end_date.replace(tzinfo=tz)
Jun Zhou
  • 1,077
  • 1
  • 6
  • 19
0

To not get a naive datetime, if myday is a string representing a date, convert it directly to a date this way:

from time import strptime

myday = date(*strptime(myday, "%Y-%m-%d")[:3])

This method avoids having to translate from naive to aware datetime.

jpaul
  • 309
  • 1
  • 5