457

我正在尝试使用 IPython 发送一封简单的邮件。我没有设置任何仍然出现此错误的模型。可以做什么?

错误:/home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/models/fields/init .py :827:RuntimeWarning:DateTimeField 收到一个幼稚的日期时间(2013-09-04 14:14:13.698105),而时区支持处于活动状态。运行时警告)

尝试过:第一步是添加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)
4

9 回答 9

650

问题不在于 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 的now(). 如果不是,则可能是现有软件包的问题,​​它获取没有时区的日期,您可以修补软件包、忽略警告或将 USE_TZ 设置为 False。

于 2013-11-20T20:16:24.277 回答
166

使用django.utils.timezone.make_aware函数让您的天真日期时间对象了解时区并避免这些警告。

它将天真的日期时间对象(没有时区信息)转换为具有时区信息的对象(如果您没有将其明确指定为第二个参数,则使用 django 设置中指定的时区):

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>
于 2017-07-13T12:27:21.380 回答
47

只是为了修复错误以设置当前时间

from django.utils import timezone
import datetime

datetime.datetime.now(tz=timezone.utc) # you can use this value
于 2018-03-06T10:37:55.493 回答
19

又快又脏——把它关掉:

USE_TZ = False

在你的settings.py

于 2019-05-07T08:17:26.627 回答
15

既可以修复警告也可以使用 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'

另一种等效方法是 using make_aware,请参阅 dmrz 帖子。

于 2019-03-10T10:40:04.720 回答
12

确保 settings.py 有 USE_TZ = True

在你的 python 文件中:

from django.utils import timezone

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

于 2020-08-23T10:39:58.740 回答
11

如果您试图在 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 是一个天真的日期时间,而 t2 是一个在 django 设置中带有时区的日期时间。

于 2019-07-17T08:19:44.440 回答
11

您还可以覆盖设置,这在测试中特别有用:

from django.test import override_settings

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

这将阻止您看到警告,同时代码中需要时区感知日期时间的任何内容都可能会给您带来问题。如果是这种情况,请参阅 kravietz 答案。

于 2019-10-16T16:36:23.243 回答
6

在模型中,不要传递值:

timezone.now()

相反,删除括号,然后传递:

timezone.now

如果您继续收到运行时错误警告,请考虑将模型字段从 DateTimeField 更改为 DateField。

于 2020-06-30T08:33:20.720 回答