Класс Window

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

Синтаксис

pythonfrom django.db.models import Window

Window(
  expression,
  partition_by=None,
  order_by=None,
  frame=None,
  output_field=None,
)

Пример . С ранжированием

Давайте создадим модель для статей с рейтингом и добавим поле с рангом каждой статьи в общем списке:

pythonfrom django.db import models
from django.db.models import Window, F
from django.db.models.functions import Rank

class Article(models.Model):
  title = models.CharField(max_length=100)
  rating = models.IntegerField()

# Добавляем ранг для каждой статьи
articles = Article.objects.annotate(
  rank=Window(
    expression=Rank(),
    order_by=F('rating').desc()
  )
)

for article in articles:
  print(f"{article.title}: rank {article.rank}")

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

python"Python Basics: rank 1"
"Django Guide: rank 2"
"Web Development: rank 2"
"JavaScript Tips: rank 4"

Пример . С разбиением на категории

Теперь добавим ранжирование внутри каждой категории, используя параметр partition_by:

pythonfrom django.db import models
from django.db.models import Window, F
from django.db.models.functions import Rank

class Article(models.Model):
  title = models.CharField(max_length=100)
  category = models.CharField(max_length=50)
  rating = models.IntegerField()

# Ранжируем статьи внутри каждой категории
articles = Article.objects.annotate(
  category_rank=Window(
    expression=Rank(),
    partition_by=F('category'),
    order_by=F('rating').desc()
  )
)

for article in articles:
  print(f"{article.category}: {article.title} - rank {article.category_rank}")

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

python"Tech: Python Basics - rank 1"
"Tech: Django Guide - rank 2"
"Tech: Web Development - rank 3"
"Science: Physics 101 - rank 1"
"Science: Chemistry Basics - rank 2"

Пример . С накопительной суммой

Рассмотрим вычисление накопительной суммы в рамках отсортированных данных с использованием Sum и Window:

pythonfrom django.db import models
from django.db.models import Window, F, Sum

class Sale(models.Model):
  product = models.CharField(max_length=100)
  date = models.DateField()
  amount = models.IntegerField()

# Вычисляем накопительную сумму продаж по датам
sales = Sale.objects.order_by('date').annotate(
  cumulative_sum=Window(
    expression=Sum('amount'),
    order_by=F('date').asc()
  )
)

for sale in sales:
  print(f"{sale.date}: {sale.amount} (cumulative: {sale.cumulative_sum})")

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

python"2026-01-01: 100 (cumulative: 100)"
"2026-01-02: 150 (cumulative: 250)"
"2026-01-03: 200 (cumulative: 450)"
"2026-01-04: 120 (cumulative: 570)"

Пример . С разбиением и накопительной суммой

Комбинируем разбиение на партиции и накопительную сумму для вычисления суммы продаж по каждому продукту отдельно:

pythonfrom django.db import models
from django.db.models import Window, F, Sum

class Sale(models.Model):
  product = models.CharField(max_length=100)
  date = models.DateField()
  amount = models.IntegerField()

# Накопительная сумма по каждому продукту
sales = Sale.objects.order_by('product', 'date').annotate(
  product_cumulative=Window(
    expression=Sum('amount'),
    partition_by=F('product'),
    order_by=F('date').asc()
  )
)

for sale in sales:
  print(f"{sale.product}: {sale.date} - {sale.amount} (cum: {sale.product_cumulative})")

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

python"Laptop: 2026-01-01 - 500 (cum: 500)"
"Laptop: 2026-01-03 - 300 (cum: 800)"
"Laptop: 2026-01-05 - 200 (cum: 1000)"
"Phone: 2026-01-02 - 400 (cum: 400)"
"Phone: 2026-01-04 - 350 (cum: 750)"

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

  • класс F,
    который позволяет ссылаться на значения полей модели в выражениях
  • класс Sum,
    который вычисляет сумму значений указанного поля
  • класс Avg,
    который вычисляет среднее значение указанного поля
  • класс Count,
    который возвращает количество объектов или записей