zoukankan      html  css  js  c++  java
  • Django中ORM过滤时objects.filter()无法对月份过滤

    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)
    
  • 相关阅读:
    【Linux开发】linux设备驱动归纳总结(三):5.阻塞型IO实现
    【Linux开发】linux设备驱动归纳总结(三):5.阻塞型IO实现
    【Linux】linux设备驱动归纳总结
    【Linux】linux设备驱动归纳总结
    【Linux开发】linux设备驱动归纳总结(三):4.ioctl的实现
    【Linux开发】linux设备驱动归纳总结(三):4.ioctl的实现
    【Linux开发】linux设备驱动归纳总结(三):3.设备驱动面向对象思想和lseek的实现
    【Linux开发】linux设备驱动归纳总结(三):3.设备驱动面向对象思想和lseek的实现
    【Linux开发】linux设备驱动归纳总结(三):2.字符型设备的操作open、close、read、write
    【Linux开发】linux设备驱动归纳总结(三):2.字符型设备的操作open、close、read、write
  • 原文地址:https://www.cnblogs.com/ChangAn223/p/10928230.html
Copyright © 2011-2022 走看看