Джанго группа по нескольким полям - PullRequest
0 голосов
/ 17 октября 2018

Я хочу преобразовать этот запрос SQL в представление Django:

SELECT color, shape, eyes, count(1) FROM animals WHERE master_id = 1 GROUP BY color, shape, eyes 

Для этого я попытался:

animals = Animals.objects.filter(id=1).values('color', 'shape', 'eyes').annotate(ct=Count('color'), dg=Count('shape'), br=Count('eyes'))

И затем зациклить результат нанайдите счетчик для каждого (не очень оптимизированный), и результат не будет хорошим.Это группировка, как я хочу, но не заботится об идентификаторе.

РЕДАКТИРОВАТЬ:

<QuerySet [
    { 'color': brown, 'shape': blabla, 'eyes': toto, 'ct': 2 },
    { 'color': black, 'shape': blabla, 'eyes': toto, 'ct': 1 },
    { 'color': yellow, 'shape': xxxxx, 'eyes': ok, 'ct': 4 }
]>

ВТОРОЕ РЕДАКТИРОВАНИЕ:

Если я попробую это:

Animals.objects.filter(
    master_id=1
).values('color', 'shape', 'eyes').annotate(
    ct=Count('id')
).order_by('color', 'shape', 'eyes')

У меня есть этот результат без подсчета:

<QuerySet [
    { 'color': brown, 'shape': blabla, 'eyes': toto},
    { 'color': black, 'shape': blabla, 'eyes': toto},
    { 'color': yellow, 'shape': xxxxx, 'eyes': ok }
]>

ПОСЛЕДНЕЕ РЕДАКТИРОВАНИЕ:

В таблице Animal нет столбца count или ct, но он мне нужен в моем результате

1 Ответ

0 голосов
/ 17 октября 2018

Полный эквивалентный запрос будет выглядеть следующим образом:

Animals.objects.filter(
    master_id=1
).values('color', 'shape', 'eyes').annotate(
    ct=Count('id')
).order_by('color', 'shape', 'eyes')

В результате будет получен QuerySet со словарями, например:

<QuerySet [
    { 'color': 0, 'shape': 2, 'eyes': 1, 'ct': 1 },
    { 'color': 0, 'shape': 3, 'eyes': 3, 'ct': 4 },
    { 'color': 1, 'shape': 0, 'eyes': 0, 'ct': 2 },
    { 'color': 2, 'shape': 2, 'eyes': 1, 'ct': 5 },
]>

Например:

>>> Animals.objects.create(color='foo', shape='bar', eyes='brown', master_id=1)
<Animal: Animal object (2)>
>>> Animals.objects.create(color='foo', shape='bar', eyes='brown', master_id=1)
<Animal: Animal object (3)>
>>> Animals.objects.create(color='foo', shape='bar', eyes='blue', master_id=1)
<Animal: Animal object (4)>
>>> Animals.objects.create(color='foo', shape='rectangle', eyes='brown', master_id=1)
<Animal: Animal object (5)>
>>> Animals.objects.create(color='red', shape='rectangle', eyes='brown', master_id=1)
<Animal: Animal object (6)>
>>> Animals.objects.filter(
...     master_id=1
... ).values('color', 'shape', 'eyes').annotate(
...     ct=Count('id')
... ).order_by('color', 'shape', 'eyes')
<QuerySet [{'color': 'foo', 'shape': 'bar', 'eyes': 'blue', 'ct': 1}, {'color': 'foo', 'shape': 'bar', 'eyes': 'brown', 'ct': 2}, {'color': 'foo', 'shape': 'rectangle', 'eyes': 'brown', 'ct': 1}, {'color': 'red', 'shape': 'rectangle', 'eyes': 'brown', 'ct': 1}]> 
...