簡體   English   中英

Django:使用前綴和注釋模型

[英]Django: Annotate model with a prefix sum

我有一個TimeTrial模型,該模型匯總了Leg的有序列表。

class TimeTrial(models.Model):
    objects = TimeTrialManager()

class Leg(models.Model):
    timetrial = models.ForeignKey(TimeTrial)
    duration = models.FloatField()
    order = models.PositiveIntegerField(default=0)

    @property
    def duration_prefix_sum(self):
        qs = Leg.objects.filter(timetrial=self.timetrial,
                                order__lte=self.order)
        return qs.aggregate(Sum('duration'))

class TimeTrialManager(models.Manager):
    def get_queryset(self):
        qs = super(TimeTrialManager, self).get_queryset()
        qs = qs.annotate(leg_count=Count('leg'))
        qs = qs.annotate(duration=Sum('leg__duration'))
        return qs

實際模型的精簡版。)

所述TimeTrialManager注釋每TimeTrial與數量Leg S和的總和Leg.duration 我想以類似的方式使用Django的annotate / aggregate來計算duration_prefix_sum ,所以當我在timetrial.leg_set.all()顯示每條腿的duration_prefix_sum時,不會引起數據庫命中。

我知道我可以編寫Python代碼來計算它:

timetrial.leg_set_annotated = []
s = 0
for l in timetrial.leg_set.all():
    s += l.duration
    l.duration_prefix_sum_computed = s
    timetrial.leg_set_annotated.append(l)

但是我寧願使用Django的注釋/聚合/案例/ When。

我已經找到了解決方案,但是我不確定它是否完全可靠。 我已經在我的項目中實現了它

我們添加過濾器timetrial__leg__order__lte=F('order')來添加包含所有階數小於或等於當前的timetrial__leg__order__lte=F('order') 然后,我們將注釋duration_prefix_sum添加為Sum('timetrial__leg__duration') ,從而計算前綴和。

from django.db.models import Sum, F
qs = Leg.objects.filter(timetrial__leg__order__lte=F('order'))
qs = qs.annotate(duration_prefix_sum=Sum('timetrial__leg__duration'))

我認為,如果使用此查詢集的代碼在'timetrial__leg'添加另一個注釋/過濾器,則此操作將失敗,因此歡迎添加使其更健壯的附加功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM