Django中日期處理注意事項(xiàng)與自定義時(shí)間格式轉(zhuǎn)換詳解
前言
我們?cè)谟肈jango創(chuàng)建models時(shí),常常會(huì)涉及時(shí)間日期字段的處理,Django里日期相關(guān)Field有DateTimeField、DateField和TimeField三種類型,看似簡單,但其中有一些容易出錯(cuò)的地方需要注意;另外,如果不習(xí)慣Django的默認(rèn)時(shí)間格式,也可以自定義的修改。
DateTimeField、DateField和TimeField,其值分別對(duì)應(yīng)著Python里的datetime.datetime、datetime.date和datetime.time三個(gè)實(shí)例,這三個(gè)Field里都有兩個(gè)參數(shù):auto_now和auto_now_add,默認(rèn)值均為False。
auto_now參數(shù)說明:
每次保存對(duì)象時(shí)自動(dòng)將字段值設(shè)置為當(dāng)前時(shí)間,能夠在保存該字段時(shí),將其值設(shè)置為當(dāng)前時(shí)間,并且每次修改model,都會(huì)自動(dòng)更新。因此這個(gè)參數(shù)在需要存儲(chǔ)“最后修改時(shí)間”的場景下,十分方便,常用類似“l(fā)ast-modified”或者"update_time"字段。
需要注意的是,該字段不能被手動(dòng)修改覆蓋;當(dāng)設(shè)置為true時(shí),只有每次調(diào)用Model.save()時(shí),才會(huì)強(qiáng)制更新為當(dāng)前時(shí)間點(diǎn);當(dāng)用其他方式更新其他字段時(shí)并不會(huì)更新:比如用QuerySet.update()方法,即使為該字段指定一個(gè)自定義的值,該字段也不會(huì)有所更改。比較直觀的表現(xiàn)形式是,如果使用django自帶的admin管理器,那么該字段在admin中是只讀的,并且無法進(jìn)行修改。
示例代碼如下:
class Datacenter(models.Model): id = models.UUIDField('機(jī)房ID', default=uuid.uuid4, primary_key=True) zone = models.ForeignKey(Zone, verbose_name='所在區(qū)域', on_delete=models.PROTECT) dc_name = models.CharField('機(jī)房', max_length=128, unique=True) networks = models.CharField('IP地址段', max_length=128, blank=True, unique=True) update_time = models.DateTimeField('更新時(shí)間', auto_now=True) def __str__(self): return self.dc_name class Meta: verbose_name = '機(jī)房配置' verbose_name_plural = '機(jī)房配置'
Datacenter的ModelAdmin代碼:
class DatacenterAdmin(admin.ModelAdmin): list_display = ['id', 'dc_name', 'zone', 'networks', 'update_time'] search_fields = ['dc_name', 'zone', 'networks'] list_filter = ['dc_name', 'zone'] ordering = ['networks', 'zone'] admin.site.register(models.Datacenter, DatacenterAdmin)
Admin界面效果圖:
點(diǎn)擊編輯頁面,會(huì)發(fā)現(xiàn)找不到‘更新時(shí)間'的編輯處,因?yàn)榇俗侄问侵蛔x,且不允許手動(dòng)修改,效果圖如下:
當(dāng)頁面“save”之后,再觀察現(xiàn)在的‘更新時(shí)間'發(fā)現(xiàn)時(shí)間已經(jīng)被修改:
auto_now_add參數(shù)說明:
設(shè)置為True時(shí),會(huì)在model對(duì)象第一次被創(chuàng)建時(shí),將字段的值設(shè)置為創(chuàng)建時(shí)的時(shí)間,以后修改對(duì)象時(shí),字段的值不會(huì)再更新。該屬性通常被用在存儲(chǔ)“創(chuàng)建時(shí)間”的場景下。與auto_now類似,auto_now_add也具有強(qiáng)制性,一旦被設(shè)置為True,就無法在程序中手動(dòng)為字段賦值,在admin中字段也會(huì)成為只讀的。
繼續(xù)沿用剛才的代碼示例,'update_time'的'auto_now'改完'auto_now_add',其他代碼不變:
class Datacenter(models.Model): id = models.UUIDField('機(jī)房ID', default=uuid.uuid4, primary_key=True) zone = models.ForeignKey(Zone, verbose_name='所在區(qū)域', on_delete=models.PROTECT) dc_name = models.CharField('機(jī)房', max_length=128, unique=True) networks = models.CharField('IP地址段', max_length=128, blank=True, unique=True) update_time = models.DateTimeField('更新時(shí)間', auto_now_add=True)
編輯更新北京聯(lián)通機(jī)房的IP地址段之后保存:
更改之后‘更新時(shí)間'并未發(fā)生改變(見下圖),因?yàn)椤產(chǎn)uto_now_add'在對(duì)象創(chuàng)建完成后即不再更新:
如何實(shí)現(xiàn)可編輯
auto_now和auto_now_add被設(shè)置為True后,這樣做會(huì)導(dǎo)致字段成為editable=False和blank=True的狀態(tài)。editable=False將導(dǎo)致字段不會(huì)被呈現(xiàn)在admin中,blank=Ture表示允許在表單中不輸入值。此時(shí),如果在admin的fields或fieldset中強(qiáng)行加入該日期時(shí)間字段,那么程序會(huì)報(bào)錯(cuò),admin無法打開;如果在admin中修改對(duì)象時(shí),想要看到日期和時(shí)間,可以將日期時(shí)間字段添加到admin類的readonly_fields中:
readonly_fields = ('save_date', 'mod_date',)
那么問題來了。實(shí)際場景中,往往既希望在對(duì)象的創(chuàng)建時(shí)間默認(rèn)被設(shè)置為當(dāng)前值,又希望能在日后修改它。怎么實(shí)現(xiàn)這種需求呢?
django中所有的model字段都擁有一個(gè)default參數(shù),用來給字段設(shè)置默認(rèn)值。可以用default=timezone.now來替換auto_now=True或auto_now_add=True。timezone.now對(duì)應(yīng)著django.utils.timezone.now(),代碼示例:
from django.utils import timezone class Datacenter(models.Model): id = models.UUIDField('機(jī)房ID', default=uuid.uuid4, primary_key=True) zone = models.ForeignKey(Zone, verbose_name='所在區(qū)域', on_delete=models.PROTECT) dc_name = models.CharField('機(jī)房', max_length=128, unique=True) networks = models.CharField('IP地址段', max_length=128, blank=True, unique=True) update_time = models.DateTimeField('更新時(shí)間', default=timezone.now()) def __str__(self): return self.dc_name class Meta: verbose_name = '機(jī)房配置' verbose_name_plural = '機(jī)房配置'
這里'update_time'字段默認(rèn)值改為timezone.now()后,再次編輯已經(jīng)能看到相應(yīng)‘更新時(shí)間'字段,并且可修改:
我們把時(shí)間天數(shù)加1天后,保存退出再觀察‘更新時(shí)間'已經(jīng)變?yōu)樽远x時(shí)間:
自定義日期格式:
剛創(chuàng)建的Django應(yīng)用,可能你看到的日期顯示格式跟下圖類似(跟LANGUAGE_CODE和TIME_ZONE有關(guān)):

如果不習(xí)慣這種格式,自己定義顯示格式的配置如下,更改Django的setting.py文件:
USE_L10N = False DATE_FORMAT = 'Y-m-d' DATETIME_FORMAT = 'Y-m-d H:i:s'
注意事項(xiàng):如果USE_L10N設(shè)置為了True,那么語言環(huán)境規(guī)定的格式具有更高的優(yōu)先級(jí)并將被應(yīng)用,即DATE_FORMAT不生效。
這里可用的格式化字符串的其他寫法參見Django官方文檔:
<https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#date>;
另外在Django頁面渲染的時(shí)候,html頁面從數(shù)據(jù)庫中讀出DateTimeField字段時(shí),顯示的時(shí)間格式和數(shù)據(jù)庫中存放的格式不一致,另外一個(gè)解決辦法:可以在頁面格式化時(shí)間,添加{{ Datacenter.updatetime|date:"Y-m-d H:i:s" }}類似的過濾器。之后刷新頁面,即可正常顯示。
相關(guān)文檔:
https://docs.djangoproject.com/en/2.0/ref/settings/
https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#std:templatefilter-date
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- java實(shí)現(xiàn)的日期時(shí)間轉(zhuǎn)換工具類完整示例
- Java Calendar日歷與Date日期的相互轉(zhuǎn)換詳解
- jQuery時(shí)間戳和日期相互轉(zhuǎn)換操作示例
- Java將日期類型Date時(shí)間戳轉(zhuǎn)換為MongoDB的時(shí)間類型數(shù)據(jù)
- Js中將Long轉(zhuǎn)換成日期格式的實(shí)現(xiàn)方法
- js時(shí)間戳與日期格式之間相互轉(zhuǎn)換
- Java日期時(shí)間字符串和毫秒相互轉(zhuǎn)換的方法
- springboot日期轉(zhuǎn)換器實(shí)現(xiàn)實(shí)例解析
相關(guān)文章
python 利用百度API識(shí)別圖片文字(多線程版)
這篇文章主要介紹了python 利用百度API識(shí)別圖片文字(多線程版),幫助大家更好的利用python進(jìn)行機(jī)器識(shí)別,感興趣的朋友可以了解下2020-12-12一篇文章搞懂python混亂的切換操作與優(yōu)雅的推導(dǎo)式
這篇文章主要給大家介紹了如何通過一篇文章搞懂python混亂的切換操作與優(yōu)雅的推導(dǎo)式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-08-08Python 動(dòng)態(tài)導(dǎo)入對(duì)象,importlib.import_module()的使用方法
今天小編就為大家分享一篇Python 動(dòng)態(tài)導(dǎo)入對(duì)象,importlib.import_module()的使用方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-08-08Python實(shí)現(xiàn)隨機(jī)生成手機(jī)號(hào)及正則驗(yàn)證手機(jī)號(hào)的方法
這篇文章主要介紹了Python實(shí)現(xiàn)隨機(jī)生成手機(jī)號(hào)及正則驗(yàn)證手機(jī)號(hào)的方法,涉及Python基于random模塊的隨機(jī)數(shù)以及基于re模塊的正則驗(yàn)證相關(guān)操作技巧,需要的朋友可以參考下2018-04-04python自動(dòng)從arxiv下載paper的示例代碼
這篇文章主要介紹了python自動(dòng)從arxiv下載paper的示例代碼,幫助大家更好的理解和學(xué)習(xí)python,感興趣的朋友可以了解下2020-12-12tensorflow實(shí)現(xiàn)簡單的卷積網(wǎng)絡(luò)
這篇文章主要為大家詳細(xì)介紹了tensorflow實(shí)現(xiàn)簡單的卷積網(wǎng)絡(luò),使用的數(shù)據(jù)集是MNIST,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05