Класс Count

Класс Count применяется в агрегации и аннотации QuerySet для вычисления количества записей. Он принимает имя поля или выражение и возвращает количество объектов, удовлетворяющих условиям. При использовании с ForeignKey и ManyToManyField позволяет подсчитывать связанные объекты.

Параметры конструктора класса Count:

Синтаксис

pythonfrom django.db.models import Count

Count(expression, distinct=False, filter=None)

Пример

Рассмотрим модель Article с полями title и author:

pythonfrom django.db import models

class Article(models.Model):
  title = models.CharField(max_length=100)
  author = models.CharField(max_length=50)
  is_published = models.BooleanField(default=True)
  created_at = models.DateTimeField(auto_now_add=True)

  def __str__(self):
    return self.title

Подсчитаем общее количество статей в базе данных:

pythonfrom myapp.models import Article
from django.db.models import Count

# Подсчет всех статей
total_articles = Article.objects.aggregate(total=Count('id'))
print(total_articles)

Результат выполнения кода:

python{"total": 10}

Пример

Используем аннотацию для подсчета количества статей для каждого автора:

pythonfrom myapp.models import Article
from django.db.models import Count

# Подсчет статей по авторам
author_counts = (Article.objects
  .values('author')
  .annotate(article_count=Count('id'))
  .order_by('-article_count'))
for item in author_counts:
  print(f"{item['author']}: {item['article_count']}")

Результат выполнения кода:

python"John Doe: 5"
"Jane Smith: 3"
"Bob Johnson: 2"

Пример

Используем параметр distinct для подсчета уникальных значений поля author:

pythonfrom myapp.models import Article
from django.db.models import Count

# Подсчет уникальных авторов
distinct_authors = Article.objects.aggregate(
  unique_authors=Count('author', distinct=True))
print(distinct_authors)

Результат выполнения кода:

python{"unique_authors": 3}

Пример

Используем параметр filter для подсчета только опубликованных статей каждого автора:

pythonfrom myapp.models import Article
from django.db.models import Count, Q

# Подсчет опубликованных статей по авторам
published_counts = (Article.objects
  .values('author')
  .annotate(
    published_count=Count('id', 
      filter=Q(is_published=True)))
  .order_by('-published_count'))
for item in published_counts:
  print(f"{item['author']}: {item['published_count']}")

Результат выполнения кода:

python"John Doe: 4"
"Jane Smith: 2"
"Bob Johnson: 1"

Пример

Используем Count с ForeignKey для подсчета связанных объектов. Рассмотрим модель Author и связанные с ней статьи:

pythonfrom django.db import models

class Author(models.Model):
  name = models.CharField(max_length=50)

  def __str__(self):
    return self.name

class Article(models.Model):
  title = models.CharField(max_length=100)
  author = models.ForeignKey(Author, 
    on_delete=models.CASCADE, 
    related_name='articles')

Подсчитаем количество статей для каждого автора с использованием аннотации:

pythonfrom myapp.models import Author
from django.db.models import Count

# Подсчет статей для каждого автора
authors_with_counts = (Author.objects
  .annotate(article_count=Count('articles'))
  .order_by('-article_count'))
for author in authors_with_counts:
  print(f"{author.name}: {author.article_count}")

Результат выполнения кода:

python"John Doe: 5"
"Jane Smith: 3"
"Bob Johnson: 2"

Смотрите также

  • класс Sum,
    который вычисляет сумму значений поля
  • класс Avg,
    который вычисляет среднее значение поля
  • метод annotate,
    который добавляет аннотации к каждому объекту QuerySet
  • метод aggregate,
    который вычисляет агрегатные значения для всего QuerySet