我每天有100k条目,我使用它们在API中输出(我有一个限制和默认偏移)。我想在我的查询集中计算值,如果它们有一个共同的owner_id,并且如果没有日期三角形的共同所有者则保留其余的值
我现在正在做什么,但看起来并不正确(它不会计算一些正确的数据,但是由于某种原因某些数据也会增加,这本来应该没有)
TrendData.objects.filter(owner__trend_type__mnemonic='posts').filter(
date_trend__date__range=[date_from, date_to]).values('owner__name').annotate(
views=(Sum('views') / date_delta),
views_u=(Sum('views_u') / date_delta),
likes=(Sum('likes') / date_delta),
shares=(Sum('shares') / date_delta),
interaction_rate=(
Sum('interaction_rate') / date_delta),
)
date_delta = date_to - date_from #<- integer
我的模特是:
class Owner(models.Model):
class Meta:
verbose_name_plural = 'objects'
TREND_OWNERS = Choices('group', 'user')
link = models.CharField(max_length=255)
name = models.CharField(max_length=255)
owner_type = models.CharField(choices=TREND_OWNERS, max_length=50)
trend_type = models.ForeignKey(TrendType, on_delete=models.CASCADE)
def __str__(self):
return f'{self.link}[{self.trend_type}]'
class TrendData(models.Model):
class Meta:
verbose_name_plural = 'Trends'
owner = models.ForeignKey(Owner, on_delete=models.CASCADE)
views = models.IntegerField()
views_u = models.IntegerField()
likes = models.IntegerField()
shares = models.IntegerField()
interaction_rate = models.DecimalField(max_digits=20, decimal_places=10)
mean_age = models.IntegerField()
source = models.ForeignKey(TrendSource, on_delete=models.CASCADE)
date_trend = models.DateTimeField()
在这种情况下,源父模型并没有真正帮助,它是从中加载的csv文件数据,因此我们不会引用它。
我想要的是,如果两天都满足views, views_u, likes, shares, interaction_rate
(比如01.01.19到10.01.2019),并且如果两天中有2个所有者计算总和,如果没有跳过,可以计算owner
的总和将它保留为一个简单的查询集,而不将其中的所有值相加,如果满足则计算并保留其余的值。我可以用python做到这一点,但我认为可以在django ORM中做到
Django ORM提供了一个conditional expressions来做这种基于条件的注释。您可以根据您提到的条件使用Case
来注释Sum
。
TrendData.objects.filter(owner__trend_type__mnemonic='posts').annotate(
views=Sum(
Case(
When("Your condition here", then=F('views')),
default=0,
output_field=IntegerField(),
)
)
...
)