【Django總結】Django的時間字段DateTimeField


一. Django的時間字段DateTimeField

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

<1>DateTimeField.auto_now

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

<2>DateTimeField.auto_now_add

  這個參數的默認值也為False,設置為True時,會在model對象第一次被創建時,將字段的值設置為創建時的時間,以后修改對象時,字段的值不會再更新。該屬性通常被用在存儲“創建時間”的場景下。與auto_now類似,auto_now_add也具有強制性,一旦被設置為True,就無法在程序中手動為字段賦值,在admin中字段也會成為只讀的。

<3>admin中的日期時間字段

  auto_now和auto_now_add被設置為True后,這樣做會導致字段成為editable=False和blank=True的狀態。editable=False將導致字段不會被呈現在admin中,blank=Ture表示允許在表單中不輸入值。此時,如果在admin的fields或fieldset中強行加入該日期時間字段,那么程序會報錯,admin無法打開;如果在admin中修改對象時,想要看到日期和時間,可以將日期時間字段添加到admin類的readonly_fields中:

 

二. Django的外鍵字段ForeignKey

有兩個數據模型欄目模型和文章模型ArticleColumn和ArticlePost

ArticleColumn:

class ArticleColumn(models.Model):
    # 用戶與欄目是“一對多”關系,所以用ForeignKey,一個用戶可以設置多個欄目,此處的user字段對應實際表中的user_id,來自於User表中主鍵
    user = models.ForeignKey(User, related_name='article_column')
    column = models.CharField(max_length=100)
    created = models.DateTimeField(auto_now_add=True)

 

ArticlePost:

復制代碼
class ArticlePost(models.Model):

    author = models.ForeignKey(User, related_name='article')
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=500)
    column = models.ForeignKey(ArticleColumn, related_name='article_column')
    body = models.TextField()
    created = models.DateTimeField(default=timezone.now())
    updated = models.DateTimeField(auto_now_add=True)
    # media/%Y%m%d/為圖片的真實放置路徑,因為settings中已經配置了MEDIA_ROOT為media文件夾,blank=True允許表單的該字段對應值為空,意思是非必填字段
    avatar = models.ImageField(upload_to='%Y%m%d/', blank=True)
復制代碼

可以看到在ArticlePost模型中有一個字段為column,且類型為ForeignKey,意思是外鍵,代表的是“多對一”的關系,第一個參數ArticleColumn是對應的模型名稱,related_name為反查時的關聯名稱。

多對一指的是,多個文章可以對應一個欄目,比如有10篇文章都是屬於django欄目的(當然一個文章也可以對應多個欄目,這樣就是多對多關系了:ManyToManyField,此處我們設計不存在這種情況),

有了外鍵關系后,那如何去查詢某篇文章對應的所屬欄目呢?

article = ArticlePost.objects.get(id=150)

article.column

 如果不使用外鍵關系,想查詢某篇文章對應的所屬欄目呢?

復制代碼
# 獲取該文章對象
article = ArticlePost.objects.get(id=150)
# 找到該文章對象對應的column_id,column_id這一列就是因為ArticlePost模型中有column字段且將ArticleColumn作為外鍵,所以將ArticleColumn模型對應表中的主鍵id的值作為column_id的值,將列名命名為column_id
article.column_id
# 根據上面查出來的id找到該欄目對象
column = ArticleColumn.objects.get(id=article.column_id)
# 輸出欄目名稱
column.column
復制代碼

 

那怎么反查某個欄目下有多少文章呢?

 

復制代碼
# 查詢出叫django的欄目
column = ArticleColumn.objects.get(column='django')
# 通過column這個實例.article_column.all(),查詢出該欄目下的所有文章,article_column就是在ArticlePost模型中的related_name的值
column.article_column.all()
# 反查django這個欄目下title中包含'list'字符串的文章
column.article_column.filter(title__contains='list')
class YourAdmin(admin.ModelAdmin):
    readonly_fields = ('save_date', 'mod_date',)
admin.site.register(Tag, YourAdmin)

<4>如何將創建時間設置為“默認當前”並且可修改

  那么問題來了。實際場景中,往往既希望在對象的創建時間默認被設置為當前值,又希望能在日后修改它。怎么實現這種需求呢?

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> 類似的過濾器。刷新頁面,即可正常顯示。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM