2016-08-08 3 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() 

が今、私はこのモデルのために照会するたびに、私は私の views.pyから updateActive()を呼び出します。

私の質問は、Electionオブジェクトを取得するたびにupdateActive()を呼び出す方法はありますか?それとも一定に更新する?

ご了承ください。

+3

それはまったく格納しないで、必要なときにそれを計算するだけですか? – RemcoGerlich

+0

これまで私がやってきたことです。私はちょうどこれを自動化する方法があるかどうか疑問に思っていた。 – Pabs

+0

自動更新についてはわかりませんが、ロジックが間違っています: 'if self.start_date> nowとself.end_date end_date'を意味します。 'self.active = start_date mhawke

答えて

1

ベストプラクティスは、モデル内にactiveフィールドをまったく持たないことです。主な理由は、単純な計算から値を生成できるときには、その値をデータベースに格納しないでください。第2の理由は、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からの結果は、クエリセットで、あなたは

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とその仕事の井戸に別のquerysetsを渡した。ツアーのお返事ありがとうございます。 – Pabs

0

モデルのカスタムマネージャーを作成することができます。クエリ自体のインスタンスのアクティブな属性を設定することはできますが、デザインの観点からは正しいとは思われません(getメソッドは照会しているデータを変更するべきではありません)。あとで手動で特定のインスタンスを無効にしたい場合があるので、アクティブな属性を持つことは理にかなっています。 あなたは)この方法は、あなたのマネージャーはこうElection.elections.all(

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() 

ようになり、バックグラウンドジョブを使用して、アクティブなフィールドを更新する可能性のいずれかのみアクティブ選挙を返します。 クラスメソッドを使用してクエリをフィルタ処理する場合は、リストの補完またはジェネレータを使用して、ElectionManager.get_querysetメソッドで必要なクエリセットを取得できます。

+0

面白いですが、私が意図しているものではありません。だから、私はアクティブなタグを更新したい。 – Pabs

関連する問題