Класс When

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

Основные параметры конструктора When:

Класс When всегда используется внутри класса Case, который объединяет несколько условий и определяет порядок их проверки.

Синтаксис

pythonfrom django.db.models import When, Case

When(condition, then=value)

Пример . Использование с аннотацией

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

pythonfrom django.db.models import When, Case, Value, CharField
from myapp.models import User

users = User.objects.annotate(
  age_status=Case(
    When(age__lt=18, then=Value('minor')),
    When(age__gte=18, then=Value('adult')),
    default=Value('unknown'),
    output_field=CharField()
  )
)

for user in users:
  print(f"{user.name}: {user.age_status}")

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

python"John: minor"
"Jane: adult"
"Bob: adult"

Пример . Использование с агрегацией

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

pythonfrom django.db.models import When, Case, Count, Q
from myapp.models import User

result = User.objects.aggregate(
  minors=Count(
    Case(
      When(age__lt=18, then=1),
      default=None,
      output_field=IntegerField()
    )
  ),
  adults=Count(
    Case(
      When(age__gte=18, then=1),
      default=None,
      output_field=IntegerField()
    )
  )
)

print(result)

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

python{"minors": 15, "adults": 85}

Пример . Использование с несколькими условиями

Создадим более сложное условное выражение, которое классифицирует пользователей по нескольким возрастным группам:

pythonfrom django.db.models import When, Case, Value, CharField
from myapp.models import User

users = User.objects.annotate(
  age_group=Case(
    When(age__lt=13, then=Value('child')),
    When(age__range=(13, 17), then=Value('teenager')),
    When(age__range=(18, 59), then=Value('adult')),
    When(age__gte=60, then=Value('senior')),
    default=Value('unknown'),
    output_field=CharField()
  )
)

for user in users:
  print(f"{user.name}: {user.age_group}")

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

python"Alice: child"
"Mike: teenager"
"Sarah: adult"
"Tom: senior"

Пример . Использование с вычисляемыми значениями

Используем класс When для условного изменения числовых полей:

pythonfrom django.db.models import When, Case, F, Value, FloatField
from myapp.models import Product

products = Product.objects.annotate(
  discounted_price=Case(
    When(price__gt=100, then=F('price') * 0.9),
    When(price__gt=50, then=F('price') * 0.95),
    default=F('price'),
    output_field=FloatField()
  )
)

for product in products:
  print(f"{product.name}: {product.discounted_price}")

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

python"Laptop: 900.0"
"Keyboard: 47.5"
"Mouse: 25.0"

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

  • класс Case,
    который объединяет несколько условий When в одно выражение
  • класс Q,
    который используется для создания сложных условий в запросах
  • класс Value,
    который преобразует значение в выражение для использования в запросах
  • класс F,
    который ссылается на значение поля модели в выражении