Джанго сложный запрос через строитель - PullRequest
0 голосов
/ 30 ноября 2018

Мне не удавалось сделать сложный запрос с использованием ORM в течение некоторого времени.Я знаю, что это возможно, поэтому я прощу помощь.

class Game(models.Model):
    no matter

class Competition(models.Model):
    game = models.ForeignKey(to='game.Game', verbose_name=_('game'), related_name='competitions',
                         on_delete=models.PROTECT)

class User(models.Mode):
    no matter

class Balance(models.Model):
    user = models.OneToOneField(to=User, on_delete=models.CASCADE, primary_key=True)

class BalanceTransaction(models.Model):
    TYPES = (
        (TYPE_COMMISSION, _('commission')),
    }
    competition = models.ForeignKey(to='competition.Competition', verbose_name=_('competition'), related_name='transactions', on_delete=models.CASCADE, null=True, blank=True)
    balance = models.ForeignKey(to=Balance, on_delete=models.CASCADE, related_name='transactions')
    amount = models.DecimalField(_('Transaction amount'), default='0.0', max_digits=28, decimal_places=18,
                             null=False, blank=False)

    type = models.CharField(_('type'), max_length=10, default=TYPE_DEPOSIT, choices=TYPES, null=False, blank=False

Я должен вернуть набор запросов игр, где каждый элемент будет иметь дополнительное поле «доход», в котором хранится сумма всех транзакцийэта игра с типом "комиссия"

    Game.objects.filter(publisher__owner=self.request.user.pk).annotate(
    income=Sum(Case(
        When(
            Q(publisher__owner__balance__transactions__type=BalanceTransaction.TYPE_COMMISSION),
            then=???,
        )
    ))

Кажется, что таким образом это будет невозможно, и мне придется использовать подзапрос, но пока мне это не удалось.

1 Ответ

0 голосов
/ 30 ноября 2018

Я не думаю, что вам нужны подзапросы или регистр, просто стандартный фильтр.

Game.objects.filter(publisher__owner=self.request.user.pk).filter(
    publisher__owner__balance__transactions__type=BalanceTransaction.TYPE_COMMISSION
).annotate(
    income=Sum('publisher__owner__balance__transactions__amount)
)

См. порядок аннотирования и предложения фильтра для объяснения того, почему это работает.

...