django中的filter日期查询属性有:year、month、day、week_day、hour、minute、second
在做复习博客项目时,我把项目从linux移到了windows,然后博客的文章归档那一块,根据月份过滤出来的结果始终是空。然后百度了一下,结果是时区的问题。
在Django的配置文件settings.py中,有两个配置参数是跟时间与时区有关的,分别是TIME_ZONE和USE_TZ
Django中TIME_ZONE默认设置的时区是America/Chicago
若TIME_ZONE设置为其它时区的话,则还要分情况:
- 如果是Windows系统,则TIME_ZONE设置是没用的,Django会使用本机的时间
- 如果为其他系统,则使用该时区的时间,如设置USE_TZ = False, TIME_ZONE = 'Asia/Shanghai', 则使用上海的UTC时间。
django查询数据库时对应的ORM语句会用使用mysql自带的一些时间处理函数如convert_tz(时间转换函数),我们在django项目的setting文件中设置的启用时区功能USE_TZ = True,设置时区 TIME_ZONE = 'Asia/Shanghai',但是mysql不认识上海这个时区,所以mysql无法获取Asia/Shanghai的正确时间,查询的时候返回空列表。
先上终极解决办法:
# 可以使用如下方式进行筛选,筛选的值格式和你DB中的格式对应,比如是2019/04/12还是2017-04-12
article_list = ArticleModel.objects.filter(status='p', add_time__startswith='2019-04-12').order_by('-add_time')
#如果只想根据年月来筛选就是
article_list = ArticleModel.objects.filter(status='p', add_time__startswith='20179-04').order_by('-add_time')
需要注意的是 月份小于10月要和数据库匹配 需要加个0,即2019年5月需要从‘2019-5’变成‘2019-05’
解决办法1:
直接在setting.py文件中设置:USE_TZ = False
但这样的话 就无法使用django的时区功能了。(存储在数据库中的时间会小8个小时)
解决办法2:
mysql官方文档写了这两种系统天生不包含时区转换的这个文件,它没有支持windows的时区转换,如图:
所以如果是在linx,直接执行下面这条命令,如图:
如果是在windows:
下载mysql时区文件:https://dev.mysql.com/downloads/timezones.html
拷贝到C:ProgramDataMySQLMySQL Server 5.7Datamysql目录下
重启mysql
登录mysql,执行:
SET GLOBAL time_zone = 'Asia/Shanghai';
SET SESSION time_zone = 'Asia/Shanghai';
SELECT @@global.time_zone,@@session.time_zone;
来源:https://blog.csdn.net/gmsGms_gms/article/details/80748208
关于django中的时区:
django文档中有说明:当使用时区时,Django存储在数据库中的所有日期时间信息都以UTC时区为准,在后台使用有时区的datetime,前台用户使用时,在网页上翻译成用户所在的时区。
即:
Django 如果开启了 Time Zone 功能,即让 Django 内部把时间全部当成 UTC 时间(北京时间为 UTC+8 )对待。所有的存储(如存储到mysql数据库)和内部处理(在后台的各种时间处理),甚至包括直接 print 显示全都是 UTC 形式的。
这个时候,在通过模板输入时间时,会把输入的时间转换成UTC的时间,在通过模板输出时间的时候,回把UTC时间(后台都是UTC时间)转换成用户所在地的时间(除非应用支持用户设置自己所在的时区,通常我们不需要关心模板的时区问题。模板在展示时间的时候,会使用 settings.TIME_ZONE 中的设置自动把 UTC 时间转成 settings.TIME_ZONE 所在时区的时间渲染。)
启用 USE_TZ = True 后,在处理时间的时候要保证下面两点:
- 保证存储到数据库中的是 UTC 时间;
- 在函数之间传递时间参数时(后台处理)确保时间已经转换成 UTC 时间;
比如,通常获取当前时间用的是
import datetime
now = datetime.datetime.now()
启用 USE_TZ = True 后,需要写成
import datetime
from django.utils.timezone import utc
utcnow = datetime.datetime.utcnow().replace(tzinfo=utc)