2016-03-31 6 views
1

ユーザープロファイルの計算フィールドを追加したいとします。 は、私は、カスタムマネージャー追加:Djangoカスタムマネージャの計算フィールド付き

class ProCalcManager(models.Manager): 

    use_for_related_fields = True 

    def get_queryset(self): 
     result = super(ProCalcManager, self).get_queryset() 
     result = result.extra(
     select={'pro': "(start_date, INTERVAL '10 days') OVERLAPS" 
         "(CURRENT_TIMESTAMP, INTERVAL '1 days')"} 
     ) 
     return result 

class Profile (models.Model): 

    objects = ProCalcManager() 
    default_manager = ProCalcManager() 

    start_date = models.DateTimeField() 

を私は使用している場合:Users.objects.first().profile.pro結果はTrueですが、Users.objects.filter(profile__pro=True)結果を{TypeError} Related Field got invalid lookup: pro

でどのようにすることができ、ユーザプロファイルに「プロ」に計算フィールドを追加するための別の更新クエリセットそれはフィルターで使用するために?

+0

は、私を修正します私は 'pro'フィールドが文字通り_startdate + 10日>現在の日付であると理解していますから、'余分なものを使う必要はありません。フィルターを使ってもできます。 – v1k45

+0

はい、このフィルタはシステムの多くの場所で使用する必要がありますので、モデルの1か所にフィルタを配置したいと考えています。 –

答えて

0

あなたがしているのは、日付を計算し、そのユーザーがproかどうかを調べることだけです。計算とフィルタリングの両方のためにSQL文を記述するのではなく、単純な.filter()を使用してそれを実現できます。

最初にget_queryset()メソッドをオーバーライドする代わりに、proという名前のプロパティをモデルに追加します。

@property 
def pro(self): 
    calculated_end_date = tz.now() + tz.timedelta(days=-10) 
    return self.start_date > calculated_end_date 

これにより、プロファイルのproプロパティにアクセスすることができます。ちょうどあなたが余分でやるように。

>>> p = Profile.objects.first() 
>>> p.pro 
>>> True 

は、その後彼らのpro値のプロファイルにフィルタを適用することができることのために、あなたはよりのためのクエリセットを書き込むことができ、代わりにマネージャーとしてそれを使用しています。

class ProCalcQuerySet(models.QuerySet): 

    def is_pro(self, value=True): 
     calculated_end_date = tz.now() + tz.timedelta(days=-10) 
     if value: 
      lookup = 'gte' 
     else: 
      lookup = 'lt' 
     filter_dict = { 
      'start_date__' + lookup: calculated_end_date 
     } 
     return self.filter(**filter_dict) 

その後

class Profile (models.Model): 

    objects = ProCalcQuerySet.as_manager() 
    default_manager = ProCalcQuerySet.as_manager() 

オブジェクト次に、あなたはこのようにそれを使用することができますモデルでそれにアクセスするために管理者としてこのクエリセットを使用します:このような何かi「があれば

In [2]: Profile.objects.is_pro(value=True) 
Out[2]: [<Profile: Profile object>] 

In [3]: Profile.objects.is_pro() 
Out[3]: [<Profile: Profile object>] 

In [4]: Profile.objects.is_pro(False) 
Out[4]: [] 

In [8]: Profile.objects.is_pro().first().pro 
Out[8]: True 
関連する問題