問題背景
添加文章時間沒問題,但為了設定博客文章按照時間分層篩選(創建時間的年份、年月&月份來搜索文章),我在blog這個django app的admin.py的ArticleAdmin類中做了如下設置:
date_hierarchy = 'create_time' # 詳細時間分層篩選
models.Article中create_time定義如下:
create_time = models.DateTimeField(u'創建時間', auto_now_add=True)
設置后,后台呈現效果:
按照時間按分層篩選時,出現了錯誤:
ValueError at /admin/blog/article/ Database returned an invalid datetime value. Are time zone definitions for your database installed? Request Method: GET Request URL: http://127.0.0.1:8800/admin/blog/article/?create_time__year=2017 Django Version: 1.11.5 Exception Type: ValueError Exception Value: Database returned an invalid datetime value. Are time zone definitions for your database installed? Exception Location: C:\Python27\lib\site-packages\django\db\models\functions\datetime.py in convert_value, line 198 Python Executable: C:\Python27\python.exe Python Version: 2.7.13 Python Path: ['E:\\Work\\django\\myblog\\apps', 'E:\\Work\\django\\myblog', 'E:\\Work\\django\\myblog', 'E:\\Work\\django\\myblog\\apps', 'C:\\Windows\\system32\\python27.zip', 'C:\\Program Files\\VisualSVN Server\\bin', 'C:\\Program Files\\VisualSVN Server\\PythonPackages', 'C:\\Python27\\DLLs', 'C:\\Python27\\lib', 'C:\\Python27\\lib\\plat-win', 'C:\\Python27\\lib\\lib-tk', 'C:\\Python27', 'C:\\Python27\\lib\\site-packages'] Server time: 星期三, 27 九月 2017 15:01:23 +0800
問題解決方案
首先需要確認數據的時區設置沒有問題,這里使用的是mysql數據庫,時區設置如下(都是依賴計算機系統的時區):
mysql> show variables like '%time_zone%'; +------------------+--------+ | Variable_name | Value | +------------------+--------+ | system_time_zone | | | time_zone | SYSTEM | +------------------+--------+ 2 rows in set, 1 warning (0.01 sec) mysql> select now(); +---------------------+ | now() | +---------------------+ | 2017-09-27 14:59:19 | +---------------------+ 1 row in set (0.00 sec) mysql> SELECT @@global.time_zone, @@session.time_zone; +--------------------+---------------------+ | @@global.time_zone | @@session.time_zone | +--------------------+---------------------+ | SYSTEM | SYSTEM | +--------------------+---------------------+ 1 row in set (0.00 sec) mysql>
其次,修改django project下的settings.py中市區配置信息:
# LANGUAGE_CODE = 'en-us' # TIME_ZONE = 'UTC' LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True #USE_TZ = True USE_TZ = False
備注:
1)為了漢化設置了本地語言編碼為LANGUAGE_CODE=‘zh-hans’,注意我這里是django1.11.1版本,如果是django1.8之前的版本不是這么設置了的而是LANGUAGE_CODE = 'zh-cn'
2)時區默認設置是‘UTC’,我這里為了和本地一樣我設置為‘Asia/Shanghai’
3)默認USE_TZ=True,這也是問題的關鍵,直接修改為USE_TZ=False
使用USE_TZ = True,需要注意問題:
參考:http://blog.csdn.net/w6299702/article/details/38782607
啟用 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)
模板
除非應用支持用戶設置自己所在的時區,通常我們不需要關心模板的時區問題。模板在展示時間的時候,會使用 settings.TIME_ZONE 中的設置自動把 UTC 時間轉成 settings.TIME_ZONE 所在時區的時間渲染。
TIME_ZONE = 'Asia/Shanghai'