前言
我們在用Django創建models時,常常會涉及時間日期字段的處理,Django里日期相關Field有DateTimeField、DateField和TimeField三種類型,看似簡單,但其中有一些容易出錯的地方需要注意;另外,如果不習慣Django的默認時間格式,也可以自定義的修改。
DateTimeField、DateField和TimeField,其值分別對應著Python里的datetime.datetime、datetime.date和datetime.time三個實例,這三個Field里都有兩個參數:auto_now和auto_now_add,默認值均為False。
auto_now參數說明:
每次保存對象時自動將字段值設置為當前時間,能夠在保存該字段時,將其值設置為當前時間,并且每次修改model,都會自動更新。因此這個參數在需要存儲“最后修改時間”的場景下,十分方便,常用類似“last-modified”或者"update_time"字段。
需要注意的是,該字段不能被手動修改覆蓋;當設置為true時,只有每次調用Model.save()時,才會強制更新為當前時間點;當用其他方式更新其他字段時并不會更新:比如用QuerySet.update()方法,即使為該字段指定一個自定義的值,該字段也不會有所更改。比較直觀的表現形式是,如果使用django自帶的admin管理器,那么該字段在admin中是只讀的,并且無法進行修改。
示例代碼如下:
class Datacenter(models.Model): id = models.UUIDField('機房ID', default=uuid.uuid4, primary_key=True) zone = models.ForeignKey(Zone, verbose_name='所在區域', on_delete=models.PROTECT) dc_name = models.CharField('機房', max_length=128, unique=True) networks = models.CharField('IP地址段', max_length=128, blank=True, unique=True) update_time = models.DateTimeField('更新時間', auto_now=True) def __str__(self): return self.dc_name class Meta: verbose_name = '機房配置' verbose_name_plural = '機房配置'
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界面效果圖:
點擊編輯頁面,會發現找不到‘更新時間'的編輯處,因為此字段是只讀,且不允許手動修改,效果圖如下:
當頁面“save”之后,再觀察現在的‘更新時間'發現時間已經被修改:
auto_now_add參數說明:
設置為True時,會在model對象第一次被創建時,將字段的值設置為創建時的時間,以后修改對象時,字段的值不會再更新。該屬性通常被用在存儲“創建時間”的場景下。與auto_now類似,auto_now_add也具有強制性,一旦被設置為True,就無法在程序中手動為字段賦值,在admin中字段也會成為只讀的。
新聞熱點
疑難解答