How to get the count of each value from different fields using Django Queries?

谁说我不能喝 提交于 2020-01-24 21:54:08

问题


I have a Django model with many fields. Let's say the model is like this:

class Foo(models.Model):
    name = models.CharField(max_length=50)
    type = models.CharField(max_length=100, blank=True)
    foo_value = models.CharField(max_length=14, blank=True)
    # ... and many many other fields

Now I need to run a query to get me all the data from all fields. This would be Foo.objects.all(), right?

Now I need for each name (which means I will group by name) to do some things. First, the problem is if I want to group by name I would do this: Foo.objects.values('name'), right? But this gets me the 'name' field value only for all records. I need all the other fields but grouped by name.

The second more important thing is, I need to get the count of each distinct value in the 'type' field as well as the sum of the 'foo_value' field associated with each 'type'. I need all this to be one record per 'name' in the returned result. The issue is, if I tried this: Foo.objects.values('name').annotate(c=Count('type'), s=Sum('foo_value')), it will get me a record for each ('name', 'type') pair.
What I need is that if I have data like this:

name    type    foo_value
x        t1        5.5
x        t1        10.0
x        t2        20.0
y        t2        15.23
y        t1        17.0

I need the result to be:

name    type_t1_count    type_t1_sum    type_t2_count    type_t2_sum
x                2                15.5                                1                20.0
y                1                17.0                                1                15.23

How to achieve something like this?


回答1:


Since django 1.8 has conditional-expressions and you can try, and you shoul use order_by to exclude default group by read docs:

from django.db.models import Count, Case, When, IntegerField, FloatField

qs = Foo.objects.values('name'
                   ).annotate(type_t1_count=Count(
                        Case(
                           When(type='t1', then=1),
                           output_field=IntegerField()
                        )
                        )
                    ).annotate(type_t1_sum=Sum(
                        Case(
                           When(type='t1', then='foo_value'),
                           default=0.0,
                           output_field=FloatField()
                        )
                        )
                    ).annotate(type_t2_count=Count(
                        Case(
                           When(type='t2', then=1),
                           output_field=IntegerField()
                        )
                        )
                    ).annotate(type_t2_sum=Sum(
                        Case(
                           When(type='t2', then='foo_value'),
                           default=0.0,
                           output_field=FloatField()
                        )
                        )
                    ).order_by('name')

the result is:

[
    {'type_t1_sum': 15.5, 'type_t1_count': 2,
     'type_t2_count': 1, 'type_t2_sum': 20.0,
     'name': 'x'},
    {'type_t1_sum': 17.0, 'type_t1_count': 1,
    'type_t2_count': 1, 'type_t2_sum': 15.23,
    'name': 'y'}
]


来源:https://stackoverflow.com/questions/46985195/how-to-get-the-count-of-each-value-from-different-fields-using-django-queries

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!