1. 程式人生 > >django model:auto_now_add 和 auto_now

django model:auto_now_add 和 auto_now

ant key form 創建 場景 date ever exc hat

創建django的model時,有DateTimeField、DateField和TimeField三種類型可以用來創建日期字段,其值分別對應著datetime()、date()、time()三中對象。這三個field有著相同的參數auto_now和auto_now_add,並且在實際使用中很容易出錯,下面是一些註意點。

DateTimeField.auto_now

auto_now = True   # 這個參數的默認值為false,設置為true時,能夠在保存該字段時,將其值設置為當前時間,並且每次修改model,都會自動更新。因此這個參數在需要存儲“最後修改時間”的場景下,十分方便。需要註意的是,設置該參數為true時,並不簡單地意味著字段的默認值為當前時間,而是指字段會被“強制”更新到當前時間,你無法程序中手動為字段賦值;如果使用django再帶的admin管理器,那麽該字段在admin中是只讀的

DateTimeField.auto_now_add

auto_now_add = True  # 這個參數的默認值也為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> 類似的過濾器。刷新頁面,即可正常顯示。

官方文檔:

DateField
class DateField(auto_now=False, auto_now_add=False, **options)
A date, represented in Python by a datetime.date instance. Has a few extra, optional arguments:

DateField.auto_now
Automatically set the field to now every time the object is saved. Useful for “last-modified” timestamps. Note that the current date is always used; it’s not just a default value that you can override.

The field is only automatically updated when calling Model.save(). The field isn’t updated when making updates to other fields in other ways such as QuerySet.update(), though you can specify a custom value for the field in an update like that.

DateField.auto_now_add
Automatically set the field to now when the object is first created. Useful for creation of timestamps. Note that the current date is always used; it’s not just a default value that you can override. So even if you set a value for this field when creating the object, it will be ignored. If you want to be able to modify this field, set the following instead of auto_now_add=True:

    1. For DateField: default=date.today - from datetime.date.today()
            # For DateTimeField: default = datetime.now  # 不要加 ()  # - from datetime.datetime.now()
    2. For DateTimeField: default=timezone.now - from django.utils.timezone.now()
The default form widget for this field is a TextInput. The admin adds a JavaScript calendar, and a shortcut for “Today”. Includes an additional invalid_date error message key.

The options auto_now_add, auto_now, and default are mutually exclusive. Any combination of these options will result in an error.

"""
Note

As currently implemented, setting auto_now or auto_now_add to True will cause the field to have editable=False and blank=True set
"""

"""
Note

The auto_now and auto_now_add options will always use the date in the default timezone at the moment of creation or update. If you need something different, you may want to consider simply using your own callable default or overriding save() instead of using auto_now or auto_now_add; or using a DateTimeField instead of a DateField and deciding how to handle the conversion from datetime to date at display time.
"""

django model:auto_now_add 和 auto_now