解決-Django使用filter過濾時間,無法獲取月份的問題
django中的filter日期查詢屬性有:year、month、day、week_day、hour、minute、second
但是但我在使用過濾查詢是卻總是無法過濾出月份,各種查資料,最後才發現是時區問題,django查詢數據庫時對應的ORM語句會用使用mysql自帶的一些時間處理函數如convert_tz(時間轉換函數),而mysql無法獲取Asia/Shanghai的正確時間,查詢的時候返回空列表。
--記錄一下排查過程:
*查看mysql日誌文件,看Django查詢數據時的ORM語句
- 打開mysql.cnf配置文件,註釋掉68 69行:【環境是ubuntu】
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
- 重啟mysql服務
sudo service mysql restart
- 查看日誌
sudo tail -f /var/log/mysql/mysql.log
# Linux命令:tail命令: 默認會顯示文件的末尾,可以動態查看文件新加入的數據
*在另外一個終端進行django語句的執行:
>>> p = Post.objects.filter(publish__year=2018,slug="view") #測試過濾年份,獲取一條數據
>>> p
[<Post: 使用基於類的試圖>]
可以看到得到的日誌如下:
>>> c = Post.objects.filter(publish__month=4,slug="view") >>> c [] #還沒解決時區問題的情況下是返回空的,所以在有可能在渲染頁面時不能獲得數據
解決方法是在終端輸入:
# MySQL安裝程序在mysql數據庫中創建時區表,但不裝載。所以必須手動裝載
mysql_tzinfo_to_sql /usr/share/zoneinfo
# 然後重啟數據庫
service mysql restart
然後重新進入Django shell過濾數據,即可查得月份的數據
這個方法也可以處理mysql設置時區時報錯的問題
使用SET GLOBAL time_zone = ‘Asia/Shanghai‘; 命令設置時區
會卻報錯ERROR 1298 (HY000): Unknown or incorrect time zone: ‘Asia/Shanghai‘。
mysql默認的時區格式並不支持這種,而是寫成 set time_zone=‘+8:00‘;這種格式,如果想要使用‘Asia/Shanghai‘的格式
就要用mysql_tzinfo_to_sql程序用來裝載時區表,也是在終端命令行輸入如下命令,跟上面的一樣
mysql_tzinfo_to_sql /usr/share/zoneinfo #第一種(一般第一種就可以了,推薦)
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -uroot mysql #第二種
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -uroot --force mysql #第三種
---了解,django中的時區問題
django中有兩個時間概念:naive time 與 active time。
naive time:就是不帶時區的時間,
Active time就是帶時區的時間。
還有一個就是UTC時間,UTC時間表示的是格林尼治平均時即可,即零區時間
datetime模塊是python自帶的包,timezone是django內的工具包,
from datetime import date,datetime
from django.utils import timezone
使用datetime.datetime.utcnow()、datetime.datetime.now()輸出的類似2015-05-11 09:10:33.080451就是不帶時區的時間(naive time),而使用django.utils.timezone.now()輸出的類似2015-05-11 09:05:19.936835+00:00的時間就是帶時區的時間(Active time),其中+00:00表示的就是時區相對性。
解決-Django使用filter過濾時間,無法獲取月份的問題