关于Django:runtimewarning: DateTimeField received a naive datetime

RuntimeWarning: DateTimeField received a naive datetime

我想用ipython发送一封简单的邮件。我没有建立任何模型仍然得到这个错误。可以做什么?

Error :
/home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/models/fields/init.py:827: RuntimeWarning: DateTimeField received a naive datetime (2013-09-04 14:14:13.698105) while time zone support is active.
RuntimeWarning)

尝试过:第一步是将USE_TZ = True添加到设置文件中并安装pytz(如果可能)。

错误更改:

1
2
3
(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)

问题不在Django设置中,而是在传递给模型的日期中。以下是时区感知对象的外观:

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

这是一个幼稚的对象:

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

所以,如果您在任何地方传递电子邮件日期(最终到达某个模型),只需使用django的now()。如果没有,那么可能是现有包在不带时区的情况下获取日期时出现问题,您可以修补包、忽略警告或将use-tz设置为false。


使用django.utils.timezone.make-aware函数使幼稚的datetime对象具有时区意识,并避免出现这些警告。

它将naive datetime对象(不带时区信息)转换为具有时区信息的对象(如果未将其显式指定为第二个参数,则使用Django设置中指定的时区):

1
2
3
4
5
6
7
8
9
10
import datetime
from django.conf import settings
from django.utils.timezone import make_aware

naive_datetime = datetime.datetime.now()
naive_datetime.tzinfo  # None

settings.TIME_ZONE  # 'UTC'
aware_datetime = make_aware(naive_datetime)
aware_datetime.tzinfo  # <UTC>


只需修正错误以设置当前时间

1
2
3
4
from django.utils import timezone
import datetime

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


可以修复警告并使用settings.py中指定的时区,这可能与UTC不同。

例如,在my settings.py中,我有:

1
2
USE_TZ = True
TIME_ZONE = 'Europe/Paris'

这里有一个解决方案,其优点是str(mydate)给出了正确的时间:

1
2
3
4
5
6
7
8
>>> 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 post。