简体   繁体   English

Django 1.8 queryset上的条件注释

[英]Conditional annotate on django 1.8 queryset

I have a model that looks something like the following: 我有一个看起来像下面的模型:

class MyStat(Model):
     metric = ForeignKey(MetricType) 
     source = ForeingKey(SourceType)

     total_units = IntegerField()
     metric_units = IntegerField()

     objects = MyQuerySet().as_manager()

The query does the following within a piece of its code 该查询在其一段代码内执行以下操作

rollup = self.order_by().values(source.name)\.
                 annotate(mu=Sum('metric_units'), tu=Sum('total_units'))

And this works great. 这很棒。 However, I would like to modify some of those annotation dependent on the metric type that is used. 但是,我想根据所使用的metric类型来修改其中一些注释。 Somehow, create a database side conditional that will annotate slightly differently (pseudo code below): 以某种方式创建一个数据库端条件,其注释方式会稍有不同(下面的伪代码):

if metric is some_metric:
      .annotate(mu=.8*Sum('metric_units'))
else:
      .annotate(mu=Sum('metric_units'))

Obviously the above syntax is invalid, but I'm wondering if there is a way to set up my queryset to do something like that on the database side 显然上述语法无效,但是我想知道是否有一种方法可以设置我的queryset在数据库端执行类似的操作

You can make conditional expresions with Case . 您可以使用Case进行条件表达式。

Let's go to the annotate part. 让我们进入带注释的部分。

Disclaimer: This code is untested 免责声明:此代码未经测试

from django.db.models import Case, Value, When, FloatField, Sum

...annotate(mu=Case(When(metric=some_metric, then=Value(.8*Sum('metric_units')),
                    default=Value(Sum('metric_units')),
                    output_field=FloatField())))

If you need to match against multiple values in a list, you can create a list of When objects: 如果需要与列表中的多个值进行匹配,则可以创建When对象的列表:

whens = []
for some_metric in some_metrics:
    whens.append(When(metric=some_metric, then=Value(some-value-here)))

...annotate(mu=Case(*whens, default=Value(Sum('metric_units')),
                            output_field=FloatField()))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM