假設我有兩個模型:
class Task(Model):
duration = models.IntegerField(default=100)
class Record(Model):
minutes_planned = models.IntegerField(default=0)
task = models.ForeignKey(Task, related_name=records)
我想獲取所有相關記錄中計劃的總分鐘數低於對象持續時間的所有對象。我一直無法在文檔中找到解決方案。有人可以指點我嗎?
Task.objects.filter(duration__gt=F('records__minutes_planned')))
Task.objects.filter(duration__gt=Sum('records__minutes_planned'))
Task.objects.filter(duration__gt=Sum(F('records__minutes_planned')))
但到目前為止沒有任何效果。第一個成功運行,但據我所知,它對它們進行了逐一比較,而不是與所有記錄的總數進行比較。
似乎 Sum 僅限於在.aggregate()
. 但是,我想檢索對象本身,而不是一組值,這就是.aggregate()
給我的。
這是作為模型管理器編寫的最終解決方案:
from django.db.models import Manager, OuterRef, Subquery, Sum
from django.db.models.functions import Coalesce
class TaskManager(Manager):
def eligible_for_planning(self, user):
from .models import Record
records = Record.objects.filter(task=OuterRef('pk')).order_by().values('task')
minutes_planned = records.annotate(total=Sum('minutes_planned')).values('total')
qs = self.model.objects.filter(user=user, status=ACTIONABLE, duration__gt=Coalesce(Subquery(minutes_planned), 0))
return qs
我們基本上是在構建第二個查詢來獲取第一個查詢所需的值。
在這種情況下,records
是第二個查詢(或SubQuery
),它通過在此管理器中查詢的任務的 pk 過濾記錄。
然後,minutes_planned
返回將與任務的duration
.
最後,整個事情作為一個Subquery
對象插入到查詢集中。如果Coalesce
沒有找到 Record 對象,請將其包裝在 a 中並添加默認值。就我而言,這是零。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句