お世話になっております。
オブジェクトでフィルターを掛ける際に、モデルで定義した関数の戻り値を使用したいのですが、方法はありますでしょうか?
モデルには期限を設定しており、
その残存日数はステータスによって異なるので、下記のような関数を定義しています。
def remainingdays(self):
if self.is_completed:
return (self.completed_at + dt.timedelta(days=7) - timezone.make_aware(dt.datetime.now())).days
if self.shipped_at:
return (self.shipped_at + dt.timedelta(days=14) - timezone.make_aware(dt.datetime.now())).days
if self.canceled_at:
return (self.canceled_at + dt.timedelta(days=3) - timezone.make_aware(dt.datetime.now())).days
if self.terminated_at:
if self.status == 80:
return (self.terminated_at + dt.timedelta(days=7) - timezone.make_aware(dt.datetime.now())).days
if self.status == 90:
return (self.terminated_at + dt.timedelta(days=3) - timezone.make_aware(dt.datetime.now())).days
if self.flag:
return (self.found_at + dt.timedelta(days=14) - timezone.make_aware(dt.datetime.now())).days
if self.due_date:
return (self.due_date - dt.date.today()).days
return 0
この戻り値を使って、filterをかけたいのですが、
色々と探し、labda等の方法を色々と試しましたが解決が出来ず。。。
お手数ですが、ご教示を頂ければ幸いです。
ご回答ありがとうございます。
当初はQを用いて分岐をかけていたのですが、
上記のモデルメソッドには順位があり、ごちゃごちゃになっておりました。
カスタムマネージャーで下記のように定義したら、動作しました。
ありがとうございます!
def activeobjects(self):
qs = self.get_queryset()
ids = []
for q in qs:
if not q.remainingdays() > 0:
ids.append(q.id)
return qs.exclude(id__in=ids)
ちなみに、該当オブジェクト.objects.prefetch_related~と定義すると何も吐かなくなってしまうのですが、
カスタムマネージャーの場合、どこにprefetch_relatedを定義すれば良いのでしょうか?
それと、forで回してしまうと、数が増えたときに大丈夫かなーという懸念が、、、笑
ですよねー
どこを調べても、カスタムマネージャーで動作しなくなるなんて書いてないのでおかしいなーと思いつつ。
return qs.select_related().exclude(id__in=ids)
上記のマネージャーでreturnのところに追加したら動作したので、ひとまず大丈夫になりました!
※qs = self.select_related().get_queryset()としても何故か駄目なのは無視して置きます。笑
うまくいって良かったです。
カスタムマネージャーを使用していても、select_relatedもprefetch_relatedもfilterをする前に事前に取得する使い方は同じような気はします。
カスタムマネージャーを使用するのはいかがでしょうか?