2017-07-29 8 views
0

既知のオブジェクトの参照を評価します。私もイベントにcan_joinメソッドを追加したいと思います:は、私はこれらの線に沿ってフィルタを持って

class Event(models.Model): 
    def is_joinable(self, current_time): 
     return self.join_time <= current_time & self.end_time >= current_time 

しかし、私はここにロジックの重複を避けるしたいと思います(実際のロジックはもう少し複雑であり、おそらく変更されます)。 is_joinableには、クエリを評価し、selfに合格するかどうかを判断する方法はありますか?あるいは、両方のメソッドを他のメソッドの上に書くことはできますか?もちろん、私は

query = Q(id=self.id) & joinable_query 
return Event.objects.filter(query).exists() 

ような何かを行うことができますが、それは、私はすでに私の手元に持っているレコードの無意味な余分なデータベースクエリを思わ。

答えて

0

query expressionを使用して、データベース上でその計算を行い、結果をブール値フィールドとして注釈を付けてから、そのフィールドでフィルタすることができます。以下のような

何か:

class EventManager(models.Manager): 
    def get_queryset(self): 
     return self.annotate(
      joinable=Case(
       When(start_date__lte=now, end_date__gte=now, then=Value(True)), 
       default=Value(False), 
       output_field=models.BooleanField() 
     )) 

今、あなたはEvent.objects.filter(joinable=True)にフィルタリングすることができ、および各イベントオブジェクトは常にTrueまたはFalseの値でjoinableフィールドを持つことになります。

(注:このフィールドはデータベースによって計算されるため、イベントがメモリ内にある間に参加可能ステータスが変更された場合、明示的に日付を変更するか、期限が迫っているためです)実際にはこれはあまり問題にならないはずです)

+0

これは非常に興味深いですが、「今」と非常に緊密に結びついています。そのため、オブジェクトの存続期間中に状態が変化すると(時間が経過し、これらのオブジェクトが非常に長く存続するセロリのタスクによって使用されるため)、更新されません。私は単体テストを非常に壊れやすいものにしているので、モデルが今のところ「今」を見ることを避けてきました。これは私がcurrent_timeをis_joinable関数に渡す理由です。しかし、非常に面白いアプローチです。 (たぶん、寿命の長いモデルのオブジェクトは、背中の背後で別の方法で変更される可能性があるため、問題です。) –

+0

はい、私はそれを私の答えに書いています。どのように代替方法があるのか​​分かりません。クエリの一部としてデータベース内の値を計算するか、Pythonメソッドとしてのみ使用するか、ロジックを複製します。 –

関連する問題