2016-08-08 75 views
1

我的模型有一個字段,如果它處於日期範圍內,則該字段應該更改。取回Django模型更新

它應該是這樣的:

class Election(models.Model) 
    start_date = models.DateTimeField(verbose_name = 'Start Date') 
    end_date = models.DateTimeField(verbose_name = 'End date') 
    active = models.BooleanField(default=False) 

    def updateActive(self): 
     now = timezone.now() 
     if self.start_date < now and self.end_date > now: 
      self.active=True 
     else: 
      self.active=False 
     self.save() 

現在,我每次查詢這個模型的時候,我打電話updateActive()從我views.py

所以,我的問題是:有沒有辦法在每次獲取Election對象時調用updateActive()?或保持不斷更新?

任何想法是值得歡迎的。

+3

它會是一個選項,根本不存儲它,只是在需要時計算它嗎? – RemcoGerlich

+0

這就是我一直在做的事。我只是想知道是否有一種方法來實現這一點。 – Pabs

+0

不確定自動更新,但邏輯看起來不正確:'如果self.start_date>現在和self.end_date end_date'這可能不是你想要的。嘗試'self.active = start_date mhawke

回答

1

最好的方法是不要在你的模型中有active字段。主要原因在於,如果可以通過簡單的計算生成值,則不應將其存儲在數據庫中。第二個原因是BooleanField無法有效索引,涉及此字段的查詢會很慢。因此,通過計算而不是進行該領域,您不會失去任何東西。最好的方法是添加一個像這樣的自定義查詢集:

class ElectionQuerySet(models.QuerySet): 
    def is_active(self): 
     return self.filter(start_date__lt=timezone.now()).filter(end_date__gt=timezone.now()) 

現在,您的模型非常簡單。

類選舉(models.Model): START_DATE = models.DateTimeField(verbose_name = '開始日期') END_DATE = models.DateTimeField(verbose_name = '結束日期')​​

objects = ElectionQuerySet.as_manager() 

現在你的模型真是簡單。

class Election(models.Model): 
    start_date = models.DateTimeField(verbose_name = 'Start Date') 
    end_date = models.DateTimeField(verbose_name = 'End date') 

    objects = ElectionQuerySet.as_manager() 

就是這樣。每次獲取對象時都不需要更新數據庫!你可以用一個簡單的方法來找出哪些是活躍與否

Election.objects.is_active() 

從IS_ACTIVE結果是一個QuerySet,你可以鏈接它像往常一樣

Election.objects.is_active().filter(...) 

,如果你想檢查是否選舉在你可以做的模板中是活躍的:

class Election(models.Model): 
    def is_active() 
     if self.start_date < now and self.end_date > now: 
      return True 
+0

這在模型中效果很好,但我在如何在HTML模板中調用自定義管理器時有點失落。 – Pabs

+0

模板在原始問題中未提及。您無法從模板(自定義或默認)訪問管理器。 – e4c5

+0

我注意到了。我只是通過不同的查詢集到我的HTML和它的工作。感謝您的巡演答案。 – Pabs

0

您可以爲模型編寫自定義管理器。雖然可以在查詢中爲實例設置活動屬性,但從設計的角度來看,它看起來不正確(get方法不應改變它正在查詢的數據)。有一個活動屬性是有意義的,因爲您可能希望手動使某個實例失效。 你既可以使用更新後臺作業活動場,這樣一來你的經理會是什麼樣子

class ElectionManager(models.Manager): 
def get_queryset(self): 
    return super().get_queryset().filter(active=True) 
class Election(models.Model): 
    start_date = models.DateTimeField(verbose_name = 'Start Date') 
    end_date = models.DateTimeField(verbose_name = 'End date') 
    active = models.BooleanField(default=False) 
    elections = ElectionManager() 

這樣Election.elections.all()將返回唯一活躍的選舉。 如果要通過類方法過濾查詢,則可以使用列表解析或生成器在ElectionManager.get_queryset方法中獲取所需的查詢集。

+0

雖然有趣,不完全是我的意圖,因爲我有一個觀點,顯示了所有通過,正在進行和即將舉行的選舉表。這就是爲什麼我想要更新主動標籤的原因。 – Pabs