django orm 時間欄位講解
建立django的model時,有DateTimeField、DateField和TimeField三種類型可以用來建立日期欄位,其值分別對應著datetime()、date()、time()三中物件。這三個field有著相同的引數auto_now和auto_now_add,表面上看起來很easy,但實際使用中很容易出錯,下面是一些注意點。
DateTimeField.auto_now
這個引數的預設值為false,設定為true時,能夠在儲存該欄位時,將其值設定為當前時間,並且每次修改model,都會自動更新。因此這個引數在需要儲存“最後修改時間”的場景下,十分方便。需要注意的是,設定該引數為true時,並不簡單地意味著欄位的預設值為當前時間,而是指欄位會被“強制”更新到當前時間,你無法程式中手動為欄位賦值;如果使用django再帶的admin管理器,那麼該欄位在admin中是隻讀的。
DateTimeField.auto_now_add
這個引數的預設值也為False,設定為True時,會在model物件第一次被建立時,將欄位的值設定為建立時的時間,以後修改物件時,欄位的值不會再更新。該屬性通常被用在儲存“建立時間”的場景下。與auto_now類似,auto_now_add也具有強制性,一旦被設定為True,就無法在程式中手動為欄位賦值,在admin中欄位也會成為只讀的。
admin中的日期時間欄位
auto_now和auto_now_add被設定為True後,這樣做會導致欄位成為editable=False和blank=True的狀態。editable=False將導致欄位不會被呈現在admin中,blank=Ture表示允許在表單中不輸入值。此時,如果在admin的fields或fieldset中強行加入該日期時間欄位,那麼程式會報錯,admin無法開啟;如果在admin中修改物件時,想要看到日期和時間,可以將日期時間欄位新增到admin類的readonly_fields中:
class YourAdmin(admin.ModelAdmin):
readonly_fields = ('save_date', 'mod_date',)
admin.site.register(Tag, YourAdmin)
如何將建立時間設定為“預設當前”並且可修改
那麼問題來了。實際場景中,往往既希望在物件的建立時間預設被設定為當前值,又希望能在日後修改它。怎麼實現這種需求呢?
django中所有的model欄位都擁有一個default引數,用來給欄位設定預設值。可以用default=timezone.now來替換auto_now=True或auto_now_add=True。timezone.now對應著django.utils.timezone.now(),因此需要寫成類似下面的形式:
from django.db import models
import django.utils.timezone as timezone
class Doc(models.Model):
add_date = models.DateTimeField('儲存日期',default = timezone.now)
mod_date = models.DateTimeField('最後修改日期', auto_now = True
html頁面從資料庫中讀出DateTimeField欄位時,顯示的時間格式和資料庫中存放的格式不一致,比如資料庫欄位內容為2016-06-03 13:00:00,但是頁面顯示的卻是Apr. 03, 2016, 1 p.m.
為了頁面和資料庫中顯示一致,需要在頁面格式化時間,需要新增<td>{{ infor.updatetime|date:"Y-m-d H:i:s" }}</td> 類似的過濾器。重新整理頁面,即可正常顯示。