如果与foreign_key_id匹配,则计算date_range查询集中的项目总和,并跳过其余部分

问题描述 投票:0回答:1

我每天有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中做到

python django django-models
1个回答
0
投票

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(),
         )
     )
     ...
)
© www.soinside.com 2019 - 2024. All rights reserved.