django оставил соединение + группировка по количеству (*), включая ноль - PullRequest
0 голосов
/ 25 февраля 2019
class ItemGroup(models.Model):
   name = models.CharField(max_length=50)

class Item(models.Model):
   name = models.CharField(max_length=50)
   group = models.ForeignKey(ItemGroup, on_delete=models.CASCADE)

Я хочу отобразить все группы элементов, и для каждой группы показать количество элементов, которые есть в группе, и включить группы, в которых нет элементов.

В SQL я использую левое соединение для этой цели:

SELECT item_group.name, COUNT(*) as item_count
FROM item_group
LEFT JOIN item ON item_group.id = item.id
GROUP BY item_group.id, item_group.name

Поэтому я получаю группы с нулевым счетом.

Как выполнить эквивалентный запрос с django ORM

1 Ответ

0 голосов
/ 25 февраля 2019

Вам нужно использовать аннотации django .Немного измените ваш внешний ключ на:

group = models.ForeignKey(ItemGroup, related_name='items', on_delete=models.CASCADE)

для удобного именования.

Затем выполните python manage.py makemigration, а затем python manage.py migrate

Затем пришло время комментировать.

from django.db.models import Count
ItemGroup.objects.annotate(no_of_items=Count('items'))

Для этого добавьте к каждому ItemGroup объекту атрибут no_of_items, который является числом items, связанным с ним.

Теперь, если вы сделаете item_group = ItemGroup.objects.get(id=1)предполагая, что группа элементов 1 имеет 3 элемента, связанных с ней, вы можете сделать item_group.no_of_items, что даст вам 3. Если бы другая группа элементов имела 0 элементов, она вернула бы ноль.

Подробнее об аннотациях см. https://docs.djangoproject.com/en/2.1/topics/db/aggregation/

...