Класс Coalesce
Класс Coalesce применяется в запросах Django для
возврата первого не-NULL значения из переданных выражений.
Он принимает два или более аргументов и возвращает значение
первого аргумента, который не равен NULL. Это особенно
полезно при работе с полями, которые могут содержать
пустые значения, позволяя задать значение по умолчанию
или выбрать первый доступный вариант из нескольких полей.
Класс Coalesce импортируется из модуля
django.db.models. Он может использоваться вместе
с методами annotate, aggregate, filter
и другими для построения сложных запросов. В выражении
можно использовать как поля модели, так и значения
Value или другие выражения.
Синтаксис
from django.db.models import Coalesce, Value
Coalesce(expression1, expression2, ..., default_value)
Пример
Рассмотрим простой пример использования Coalesce
для замены NULL значений в поле:
from django.db.models import Coalesce, Value
from myapp.models import Article
# Если поле summary равно NULL, используем пустую строку
articles = Article.objects.annotate(
display_summary=Coalesce('summary', Value(''))
)
for article in articles:
print(article.display_summary)
Результат выполнения кода:
"Short article summary"
""
"Another summary text"
Пример
Давайте используем Coalesce для выбора первого
непустого поля из нескольких вариантов:
from django.db.models import Coalesce, Value
from myapp.models import User
# Приоритет полей: nickname, first_name, username
users = User.objects.annotate(
display_name=Coalesce(
'nickname',
'first_name',
'username',
Value('Anonymous')
)
)
for user in users:
print(user.display_name)
Результат выполнения кода:
"john_doe"
"Anonymous"
"alice_w"
"bob"
Пример
Используем Coalesce в сочетании с другими
выражениями для построения более сложной логики:
from django.db.models import Coalesce, F, Value, Sum
from datetime import date
from myapp.models import Order
# Если дата оплаты не установлена, используем дату создания
orders = Order.objects.annotate(
effective_date=Coalesce(
'paid_at',
'created_at',
Value(date.today())
)
).filter(
effective_date__gte=date(2025, 1, 1)
)
for order in orders:
print(order.id, order.effective_date)
Результат выполнения кода:
(1, datetime.date(2025, 1, 15))
(2, datetime.date(2025, 1, 20))
(3, datetime.date(2025, 2, 1))
Пример
Используем Coalesce с агрегацией для обработки
суммарных значений:
from django.db.models import Coalesce, Sum, Value
from myapp.models import Product
# Если сумма продаж равна NULL, заменяем на 0
result = Product.objects.aggregate(
total_sales=Coalesce(Sum('sales'), Value(0))
)
print(result['total_sales'])
Результат выполнения кода:
"15750"