2013-02-28 5 views
1

У меня есть ValuesQuerySet, называемый data.Django Агрегация значений queryset

Я пытаюсь получить сводной подсчет всех типов для каждого объекта

data.values('type') производит этот выход:

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

Я хочу, чтобы получить разбивку как это (может быть больше, чем просто «внутренний» и «внешний», как выбор Это может быть до 20 различных типов:.

internal: 2 
external: 2 

Я пытаюсь это, но это просто возвращает пустой словарь ...

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

Аннотировать производит Нежелательные результаты, а также:

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) 
+0

Каков тип 'data', каков тип' data.values ​​('type') '? –

+0

Это ValuesQuerySet – Austin

ответ

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

В HTML:

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

Тест:

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

ОБНОВЛЕНО:

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 %} 
+0

Это все еще возвращает пустой словарь для меня. У меня почти 500 тыс. Объектов в этой модели, но ничего не было получено из этого запроса. – Austin

+0

@Austin попытается изменить агрегат для аннотации. После этого в вашем тестовом шаблоне, например {{lists}}, не используйте forloop. Это для тестирования, чтобы мы знали, есть ли запрос – catherine

+0

. Я получаю несколько желаемых результатов от использования аннотата. Является ли проблема наличием ValuesQuerySet по сравнению с QuerySet? Я хотел бы попытаться избежать другого вызова базы данных, поскольку моя переменная «data» исходит из использования запроса, который использует фильтр и исключение. Затем я получаю от них значения(). Наверное, я просто пытаюсь понять, почему мой оригинальный код не работает. – Austin

1

Они несколько подход, давайте supose вы хотите получить результаты в словаре, легкий путь:

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

Для нескольких QuerySet вы можете использовать itertools, это перевести работу с уровня базы данных на уровень django. Это означает, что это всего лишь решение для небольших запросов.

from itertools import groupby 
results = groupby(data.all(), lambda x: x.type) 
+0

Я должен был упомянуть, что может быть более двух вариантов. До 20, кроме «внутреннего» и «внешнего», – Austin