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:\ProgramData\MySQL\MySQL Server 5.7\Data\mysql目錄下
重啟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)