0

https://docs.djangoproject.com/en/dev/ref/models/conditional-expressions/https://docs.djangoproject.com/en/dev/ref/models/expressions/我可以看到我可以用 Django 1.8 做更复杂的注释。

通常我会使用

return qs.extra(select={
  my_sum: "
    SELECT SUM(price)
    FROM some_table_name
    WHERE group_id IN (
      SELECT m2.id
      FROM other_table_name m2
      WHERE m2.some_field_name = 'some value'
    )
  "})

使用 Django ORM 中的附加功能可以实现这一点吗?

4

1 回答 1

0

以上是可能的,并且在Django Documentation on Conditional Aggregation中有介绍。

在示例中,他们展示了

from django.db import models

class Client(models.Model):
    REGULAR = 'R'
    GOLD = 'G'
    PLATINUM = 'P'
    ACCOUNT_TYPE_CHOICES = (
        (REGULAR, 'Regular'),
        (GOLD, 'Gold'),
        (PLATINUM, 'Platinum'),
    )
    name = models.CharField(max_length=50)
    registered_on = models.DateField()
    account_type = models.CharField(
        max_length=1,
        choices=ACCOUNT_TYPE_CHOICES,
        default=REGULAR,
    )

然后对其执行聚合:

>>> from django.db.models import IntegerField, Sum

>>> Client.objects.aggregate(
    regular=Sum(
        Case(
            When(account_type=Client.REGULAR, then=1),
            output_field=IntegerField()
        )
    ),
    gold=Sum(
        Case(
            When(account_type=Client.GOLD, then=1),
            output_field=IntegerField()
        )
    ),
    platinum=Sum(
        Case(
            When(account_type=Client.PLATINUM, then=1),
            output_field=IntegerField()
        )
    )
)

>>> {'regular': 2, 'gold': 1, 'platinum': 3}

所以是的,这是可能的。鉴于您上面的示例,它将大致如下:

from django.db.models import IntegerField, Sum

SomeTable.objects.aggregate(
    price_sum=Sum(
        Case(
            When(other_model__some_field_name='some_value', then='price'),
             default=0,
             output_field=IntegerField()
        )
    )
)
于 2015-04-15T14:15:14.243 回答