Класс Concat
Класс Concat применяется в сочетании с методом annotate
для создания нового поля, содержащего результат объединения
нескольких выражений. В качестве аргументов конструктор принимает
одно или несколько выражений (поля моделей, строковые литералы
или объекты Value). Также можно передать именованный
параметр output_field для явного указания типа поля результата.
Объединение выполняется в том порядке, в котором переданы аргументы.
Синтаксис
from django.db.models import Concat, Value, F
from django.db.models.functions import Concat
# Базовое использование
Concat(expression1, expression2, ..., output_field=CharField())
# Использование с F и Value
Concat(F('first_name'), Value(' '), F('last_name'))
# В annotate
Model.objects.annotate(full_name=Concat(...))
Пример
Объединим имя и фамилию пользователя с пробелом между ними:
from django.db.models import Concat, Value, F
from django.db.models.functions import Concat
from myapp.models import User
# Получаем пользователей с полным именем
users = User.objects.annotate(
full_name=Concat('first_name', Value(' '), 'last_name')
)
for user in users:
print(user.full_name)
Результат выполнения кода:
"John Doe"
"Jane Smith"
"Bob Johnson"
Пример
Объединим несколько полей статьи в одно строковое представление:
from django.db.models import Concat, Value, F
from django.db.models.functions import Concat
from myapp.models import Article
# Создаем строку "title (author) - created_at"
articles = Article.objects.annotate(
info=Concat(
'title',
Value(' ('),
'author',
Value(') - '),
'created_at'
)
)
for article in articles:
print(article.info)
Результат выполнения кода:
"Django Basics (John) - 2025-01-15 10:30:00"
"Python Tips (Jane) - 2025-01-20 14:45:00"
Пример
Используем Concat с условным объединением с помощью Case:
from django.db.models import Concat, Value, F, Case, When, Q
from django.db.models.functions import Concat
from myapp.models import Product
# Создаем описание продукта с учетом наличия скидки
products = Product.objects.annotate(
description=Case(
When(
Q(discount__gt=0),
then=Concat(
'name',
Value(' (Скидка '),
'discount',
Value('%)')
)
),
default=Concat('name', Value(' (Без скидки)')),
output_field=CharField()
)
)
for product in products:
print(product.description)
Результат выполнения кода:
"Laptop (Скидка 15%)"
"Smartphone (Скидка 10%)"
"Headphones (Без скидки)"