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)