问题
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