Рассчитать сумму элементов в наборе запросов date_range, если они совпадают с foreign_key_id, и пропустить остальные - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть 100 000 записей в день, и я использую их для вывода в 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, если owner встречается за оба дня (скажем, с 01.01.19 по 10.01.2019) и если есть 2 владельцав оба дня вычислите сумму, если не пропустите, и оставьте ее как простой набор запросов без суммирования ВСЕХ значений в ней, если встретите, то рассчитайте и оставьте все остальное как есть.Я могу сделать это с питоном, но я думаю, что это можно сделать в Django ORM

1 Ответ

0 голосов
/ 16 апреля 2019

Django ORM предоставляет условные выражения для выполнения этого вида условных аннотаций. Вы можете использовать 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(),
         )
     )
     ...
)
...