django开启时区设置USE_TZ = True时,如果想查询某一天或者某个月的数据,那大概率会返回一个空的queryset。
如下:
>>> Supplier.objects.filter(create_time__month=7)
<QuerySet []>
原因:
在查询之前,日期时间字段将转换为指定时区的时间,而转化时需要在数据库中定义时区表。
官方文档queryset.
解决办法:
执行如下命令,将系统时区文件到入到数据库表中:
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p123456 mysql
测试效果:
>>> Supplier.objects.filter(create_time__month=7)
<QuerySet [<Supplier: 腾讯云>, <Supplier: OneCloud>, <Supplier: 阿里云>]>
题外话:
LANGUAGE_CODE = 'zh-Hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = True REST_FRAMEWORK = { 'DATETIME_FORMAT': '%Y-%m-%d %H:%M:%S', ... }
开启USE_TZ = True时,django会把时间转为UTC时间存储到数据库。
配合drf序列化时,会根据TIME_ZONE配置,将UTC时间转为TIME_ZONE时间。TIME_ZONE默认为东部标准时间(比UTC时间慢5小时)。
反序列化时,前端可以传带时区的时间对象(2023-05-05T08:10:41.000Z),也可以传不带时区的字符串(2023-05-05 08:10:41)django都会把该时间转为utc时间存储到数据库。如果是字符串,则将字符串按照TIME_ZONE时区处理转为utc时间。