Question

I have a ValuesQuerySet called data.

I am trying to get a summary count of all the type for each object

data.values('type') produces this output:

[{'type': u'internal'}, {'type': u'internal'}, {'type': u'external'}, {'type': u'external'}]

I want to get a breakdown like this (there can be more then just 'internal' and 'external' as choices. This could be up to 20 different types:

internal: 2
external: 2

I'm trying this but it's just returning a empty dictionary...

data.values('type').aggregate(Count('type'))

Annotate is producing undesirbale results as well:

data.values('type').annotate(Count('type'))


[{'type': u'internal', 'type_count': 1}, {'type': u'internal', 'type_count': 1}, {'type': u'external', 'type_count': 1}, {'type': u'external', 'type_count': 1}]

Models.py

class Purchase(models.Model):    

    type = models.ForeignKey(Types)
Was it helpful?

Solution

 lists = ModelName.objects.values('type').annotate(count=Count('type'))

In html:

 {% for list in lists %}
     {{list.type}} - {{list.count}}<br/>
 {% endfor %}

Test:

 {{lists}}
 //don't use forloop yet. This will tests if the above query produce data or it is empty

UPDATED:

def view_name(request):
    lists = ModelName.objects.values_list('type', flat=True).distinct()
    types = []
    for list in lists:
        type_count = ModelName.objects.filter(type=list.type).count()
        types.append({'type': list.type, 'count': type_count})

    return render(request, 'page.html', {
            'types': types,
    })

{% for type in types %}
    {{type.type}} - {{type.count}}
{% endfor %}

OTHER TIPS

They are several approach, let's supose you want results in a dictionary, the easy way is:

results = { 'internal': data.filter( value = 'internal'  ).count(),
            'external': data.filter( value = 'external'  ).count() }

For few queryset you can use itertools, this translate work from database layer to django tier. That means that it is only a solution for little querysets.

from itertools import groupby
results = groupby(data.all(), lambda x: x.type)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top