django naive datetime问题

naive datetime问题,其实就是datetime数据没有携带时间就传递给了模型类

现象:
D:\anaconda3\envs\schedule_devops\lib\site-packages\django\db\models\fields_init_.py:1367: RuntimeWarning: DateTimeField NodeStopRecord.stop_time received a naive datetime (2024-11-16 02:34:07.905087) while time zone support is active.
warnings.warn("DateTimeField %s received a naive datetime (%s)"

一番摸索发现: 当我们在django settings.py 中配置了 LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' USE_TZ = True 以后,也就是启动了django 自动实现utc时间和本地时间转换机制以后,正常情况下我们从页面操作的数据保存到数据中,时间和日期自动会存储为utc时间和日期(比本地时间 -8h)。但是,如果我们自己写的代码往数据库中插入数据,调用ORM 模型类传递了没有时区的datetime 就会报上面的错误。模型类会提示我们 django 模型接收到了一个没有时区的datetime,简称(naive datetime),模型类期望接收aware datetime 时间(有时区的datetime)。虽然,模型类不会强制限制我们,当我们传递了 naive datetime 时间以后也是会正常存储到数据中,只不过会发警告提示我们。我就是强迫症,看到一堆标红的警告不太舒服。那解决呢,也简单就是我们给datetime 加上时区信息在传递给模型类就不会有红色提示信息了。

我的模型类
class NodeStopRecord(models.Model):
    """
    暂停记录
    """
    node_name = models.CharField(max_length=20, verbose_name='节点英文名')
    node_status = models.SmallIntegerField(verbose_name="节点状态")
    stop_time = models.DateTimeField(verbose_name='暂停时间')
    run_time = models.DateTimeField(verbose_name='开启时间', null=True)
    create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")


使用 python manage.py shell 给数据库添加几条数据
>>> naive_datetime = datetime.now() 
>>>
>>> naive_datetime                                                                              
datetime.datetime(2024, 11, 16, 11, 13, 39, 741807)  

>>> NodeStopRecord.objects.create(node_name='h123',node_status=100, stop_time=naive_datetime)   
D:\anaconda3\envs\schedule_devops\lib\site-packages\django\db\models\fields\__init__.py:1367: RuntimeWarning: DateTimeField NodeStopRecord.stop_time received a naive datetime (2024-11-16 11:13:39.741807) while time zone support is active.
  warnings.warn("DateTimeField %s received a naive datetime (%s)"
<NodeStopRecord: NodeStopRecord object (533)>
报错出现了

给datetime 加上时区传递给模型类
>>> import pytz
>>> tz = pytz.timezone('Asia/Shanghai')
>>> aware_datetime = tz.localize(naive_datetime)  
>>>
>>> aware_datetime
datetime.datetime(2024, 11, 16, 11, 13, 39, 741807, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)
>>> NodeStopRecord.objects.create(node_name='x123',node_status=101, stop_time=aware_datetime)  
<NodeStopRecord: NodeStopRecord object (535)>
向数据据库插入数据,报错消失了

去数据库查询数据
mysql> select * from nodestoprecord where node_status >= 100;
+-----+-----------+-------------+----------------------------+----------+----------------------------+----------------------------+
| id  | node_name | node_status | stop_time                  | run_time | create_time                | update_time                |
+-----+-----------+-------------+----------------------------+----------+----------------------------+----------------------------+
| 533 | h123      |         100 | 2024-11-16 03:13:39.741807 | NULL     | 2024-11-16 03:14:48.018860 | 2024-11-16 03:14:48.018860 |
| 535 | x123      |         101 | 2024-11-16 03:13:39.741807 | NULL     | 2024-11-16 03:17:59.670702 | 2024-11-16 03:17:59.670702 |
+-----+-----------+-------------+----------------------------+----------+----------------------------+----------------------------+
2 rows in set (0.00 sec)
posted on 2024-11-16 11:36  进取  阅读(3)  评论(0编辑  收藏  举报