Django 1.8中的复杂注释

时间:2015-01-28 20:32:52

标签: mysql django django-models django-queryset django-1.8

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中的附加功能可以实现这一点吗?

1 个答案:

答案 0 :(得分: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()
        )
    )
)