2

Our company has been a long-time user of Django -- for more than 10 years. We are currently running Django 1.11.26. We've dealt with a lot of datetime-related issues over the years, but our current issue is proving challenging.

Our goal is to do the following:

  • use Django's timezone support (setting USE_TZ=True) with UTC as default time zone
  • for a couple of denormalized fields (daily rollups of energy data) store naive datetimes

As is documented in many Stack Overflow questions, Django will issue a warning with datetime field values set to a naive datetime: RuntimeWarning: DateTimeField received a naive datetime...while time zone support is active.

We think our use case for storing naive datetime is a reasonable one. While for almost all our datetime fields it make sense to use UTC, for certain kinds of daily rollups we want to store a naive/agnostic datetime indicating the start datetime of the day in the local time zone (multiple time zones for different objects). By using a naive datetime, we are able to use datetime-related filters. Therefore if we are summarizing certain kinds of energy rollups for a given datetime, we can find the rollup for the same local datetime for buildings in any time zone (Los Angeles, Chicago, Boston) by filtering in various ways on that naive local datetime.

Here are some things we've tried:

  • Saving the local/naive datetime as an aware datetime with the given local timezone. This doesn't work because Django will always convert to the UTC equivalent. And we can understand why that happens, in part because MySQL 5.6 DATETIME fields are not timezone-aware.
  • Overriding a rollup model's save method with override_settings(USE_TZ=False). This does suppress the runtime warnings about a naive datetime, but it forces all datetimes in the model to be saved as naive. And it seems hackish, since override_settings is intended for testing.

The only workaround we have right now is to tell Django that this loca/naive datetime field is UTC -- so no time conversion is done when saving and no runtime warnings are emitted because it is an aware datetime. But it ultimately is wrong. These are not UTC datetimes. They are intentionally naive, denormalized datetimes. And we are concerned that could bite us, especially as Django evolves its time zone support.

Are there other possible solutions for this issue we haven't considered? Thanks in advance for considering the question.

  • One solution would be to make a [custom model field](https://docs.djangoproject.com/en/dev/howto/custom-model-fields/), inheriting from `DateTimeField`, that stores naive datetimes by adding or removing UTC during conversions. That should avoid the warnings, and be better than the workaround you mention above since your application code will be working with naive datetimes. Also see my answer [here](https://stackoverflow.com/questions/55101547/storing-wall-clock-datetimes-in-django-postgres/55104105#55104105). – Kevin Christopher Henry Nov 18 '19 at 06:54
  • Kevin, thank you for this helpful comment. Creating a custom model field was a little more of a change than we wanted to make in this case, but I can see that it would be a reasonable approach. Your other post has good suggestions as well. – user1521368 Nov 19 '19 at 15:05

1 Answers1

1

To filter or suppress warnings, you can use warnings.filterwarnings:

You can try adding something like this to settings.py to filter the warning:

from warnings import filterwarnings
filterwarnings('ignore', message=r'.*received a naive datetime')

You may need to fiddle with the filterwarnings call to suppress the warning as needed.

2ps
  • 15,099
  • 2
  • 27
  • 47
  • Thank you for this suggestion. It seems like the most practical solution for now, and it is working for us. To target the particular fields that should accept naive datetimes, we did fiddle with the regex -- so we could still receive runtime warnings if there are naive datetimes referenced with other fields. – user1521368 Nov 19 '19 at 15:08