RuntimeWarning: DateTimeField получил наивное datetime

Я пытаюсь отправить простую почту, используя IPython. Я не настроил ни одной модели, все еще получающей эту ошибку. Что можно сделать?

Ошибка: /home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/models/fields/init.py: 827: RuntimeWarning: DateTimeField получил наивное datetime (2013-09-04 14:14:13.698105) при активной поддержке часового пояса. RuntimeWarning)

Попробовал: первый шаг - добавить USE_TZ = True в файл настроек и установите pytz (если возможно).

Ошибка изменена:

(learn)sourabh@sL:~/Django/learn/event$ python manage.py shell
/home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py:53: RuntimeWarning: SQLite received a naive datetime (2013-09-05 00:59:32.181872) while time zone support is active.
  RuntimeWarning)

13 ответов

Решение

Проблема не в настройках Django, а в дате, переданной модели. Вот как выглядит объект с учетом часового пояса:

>>> from django.utils import timezone
>>> import pytz
>>> timezone.now()
datetime.datetime(2013, 11, 20, 20, 8, 7, 127325, tzinfo=pytz.UTC)

А вот наивный объект:

>>> from datetime import datetime
>>> datetime.now()
datetime.datetime(2013, 11, 20, 20, 9, 26, 423063)

Так что, если вы передаете дату электронной почты в любом месте (и она в конечном итоге попадает в какую-то модель), просто используйте Django's now(), Если нет, то это, вероятно, проблема с существующим пакетом, который извлекает дату без часового пояса, и вы можете исправить пакет, проигнорировать предупреждение или установить для USE_TZ значение False.

Используйте функцию django.utils.timezone.make_aware, чтобы ваши наивные объекты даты и времени знали часовой пояс и избегали этих предупреждений.

Просто чтобы исправить ошибку, чтобы установить текущее время

from django.utils import timezone
import datetime

datetime.datetime.now(tz=timezone.utc) # you can use this value

Быстро и грязно - выключите его:

USE_TZ = False

в вашем settings.py

Убедитесь , что в settings.py естьUSE_TZ = True

В вашем файле python:

from django.utils import timezone

timezone.now() # use its value in model field

Можно как исправить предупреждение, так и использовать часовой пояс, указанный в settings.py, который может отличаться от UTC.

Например в моем settings.py у меня есть:

USE_TZ = True
TIME_ZONE = 'Europe/Paris'

Вот решение; преимущество в том, что str(mydate) дает правильное время:

>>> from datetime import datetime
>>> from django.utils.timezone import get_current_timezone
>>> mydate = datetime.now(tz=get_current_timezone())
>>> mydate
datetime.datetime(2019, 3, 10, 11, 16, 9, 184106, 
    tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)
>>> str(mydate)
'2019-03-10 11:16:09.184106+01:00'

Другой эквивалентный метод использует make_awareсм. сообщение dmrz.

Вы также можете переопределить настройки, что особенно полезно в тестах:

from django.test import override_settings

with override_settings(USE_TZ=False):
    # Insert your code that causes the warning here
    pass

Это предотвратит появление предупреждения, в то же время все, что в вашем коде требует даты и времени с учетом часового пояса, может вызвать проблемы. Если это так, см. Ответ Кравица.

Если вы пытаетесь преобразовать наивное datetime в datetime с часовым поясом в django, вот мое решение:

>>> import datetime
>>> from django.utils import timezone
>>> t1 = datetime.datetime.strptime("2019-07-16 22:24:00", "%Y-%m-%d %H:%M:%S")
>>> t1
    datetime.datetime(2019, 7, 16, 22, 24)
>>> current_tz = timezone.get_current_timezone()
>>> t2 = current_tz.localize(t1)
>>> t2
    datetime.datetime(2019, 7, 16, 22, 24, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)
>>>

t1 - это наивное datetime, а t2 - это datetime с часовым поясом в настройках django.

Вот документ о проблеме, с которой вы столкнулись часовой пояс и расписание

В модели не передавайте значение:

timezone.now()

Скорее удалите круглые скобки и передайте:

timezone.now

Если вы продолжаете получать предупреждение об ошибке во время выполнения, рассмотрите возможность изменения поля модели с DateTimeField на DateField.

Я использую функцию для сокрытияdate->datetimeизвестный формат, например:

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

def date_to_datetime_aware(d:date) -> datetime:
    dt = datetime.combine(d, datetime.min.time())
    dt_aware = timezone.make_aware(dt)
    return dt_aware

Это помогает мне избежать Django RuntimeWarning.

Если вам нужно преобразовать фактическую строку даты в объект даты, я избавился от предупреждения, просто используяastimezone:

      >>> from datetime import datetime, timezone
>>> datetime_str = '2013-09-04 14:14:13.698105'
>>> datetime_object = datetime.strptime(datetime_str, "%Y-%m-%d %H:%M:%S.%f")
>>> datetime_object.astimezone(timezone.utc)
datetime.datetime(2013, 9, 4, 6, 14, 13, 698105, tzinfo=datetime.timezone.utc)

Я столкнулся с этим предупреждением при использовании следующей модели.

      from datetime import datetime

class MyObject(models.Model):
    my_date = models.DateTimeField(default=datetime.now)

Чтобы исправить это, я переключился на следующее значение по умолчанию.

      from django.utils import timezone

class MyObject(models.Model):
    my_date = models.DateTimeField(default=timezone.now)
Другие вопросы по тегам