Django设置USE_TZ为True后使用mysql查询可能会出现的问题

django项目的settings.py中设置了USE_TZ=True后,不管TIME_ZONE设置的是什么,存入数据库的都是UTC时间,取出来时会转成当前时区的时间来显示。具体USE_TZ的作用在这里就不细说了。

环境说明

Django 3.2.8版本
myql使用的是8.0.25版本
windows10系统

出现的问题

最开始项目中使用的还是sqlite,项目中有个Model类包含了一个DateTimeField,在sqlite时查询是正常的。
下面是示例:

# 查询文章年份为2021年且月份为10月的
Article.objects.filter(post_datetime__year=2021, post_datetime__month=10)

同样的语句,同样的数据,当我迁移到mysql后就出现了上面的语句查询不出数据的情况,如果只查询年份就有结果,但是一旦加上查询月份就没有结果。

解决方法

Queryset中有个query的属性,可以显示查询具体执行了什么sql语句。
具体执行的sql语句:

SELECT `mainapp_article`.`id`, `mainapp_article`.`article_id`, `mainapp_article`.`title`, `mainapp_article`.`content`, `mainapp_article`.`post_datetime`, `mainapp_article`
.`likes`, `mainapp_article`.`category`, `mainapp_article`.`read_count`, `mainapp_article`.`kind_id` FROM `mainapp_article` WHERE (`mainapp_article`.`post_datetime` BETWEEN
 2020-12-31 16:00:00 AND 2021-12-31 15:59:59.999999 AND EXTRACT(MONTH FROM CONVERT_TZ(`mainapp_article`.`post_datetime`, 'UTC', 'Asia/Shanghai')) = 10) ORDER BY `mainapp_a
rticle`.`post_datetime` DESC

其中出问题的是下面这个:

EXTRACT(MONTH FROM CONVERT_TZ(`mainapp_article`.`post_datetime`, 'UTC', 'Asia/Shanghai')) = 10)

Django中的settings.py我将TIME_ZONE设置为了Asia/shanghai,由于USE_TZ的值为True,所以会在查询数据时将数据库中存储的时间由UTC转为Asia/shanghai。DatetimeField对应着mysql里面的datetime类型。
CONVERT_TZ转换时区有以下两种形式:

-- 第一种
SELECT CONVERT_TZ('2021-10-17 13:51:53.777000','Asia/Shanghai','UTC') as cvt;
-- 第二种
SELECT CONVERT_TZ('2021-01-03 12:00:00','+00:00','+10:00')

windows中mysql没有时区表,所以使用第一种方式会导致查询不到数据,添加时区表就可以解决这个查询不到数据的问题了。
加载时区表可以参照这里

当然,直接在Django项目中设置USE_TZ为False也可以解决这个问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值