Метод alias
Метод alias применяется к QuerySet и добавляет
выражение в запрос, присваивая ему псевдоним. Этот
псевдоним может быть использован в других частях запроса,
например, в annotate или order_by. В отличие
от annotate, метод alias не добавляет
выражение в результаты выборки.
Синтаксис
Model.objects.alias(**expressions)
Метод принимает один или несколько именованных аргументов, где имя становится псевдонимом, а значение - выражением для вычисления.
Пример . Использование с order_by
Допустим, у нас есть модель статьи:
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
likes = models.IntegerField(default=0)
views = models.IntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
Рассмотрим пример использования alias для
сортировки статей по популярности:
from myapp.models import Article
from django.db.models import F
popular_articles = Article.objects.alias(
popularity=F('likes') + F('views') * 2
).order_by('-popularity')
for article in popular_articles:
print(f"{article.title}: {article.likes + article.views * 2}")
Результат выполнения кода:
"Popular Article 1: 150"
"Popular Article 2: 120"
"Popular Article 3: 80"
Пример . С filter и annotate
Покажем, как использовать alias вместе с
annotate для фильтрации по вычисляемому полю:
from myapp.models import Article
from django.db.models import F, Value, CharField
from django.db.models.functions import Concat
res = Article.objects.alias(
full_title=Concat(F('title'), Value(' - '), F('content'))
).filter(
full_title__icontains='django'
).annotate(
title_length=len('title')
)
for article in res:
print(f"{article.title}: {article.title_length}")
Результат выполнения кода:
"Django Article: 13"
"Learn Django: 11"
Пример . С аннотацией
Метод alias может быть полезен для создания
промежуточных вычислений:
from myapp.models import Article
from django.db.models import F, Case, When, IntegerField
res = Article.objects.alias(
engagement=F('likes') + F('views')
).annotate(
status=Case(
When(engagement__gt=100, then=Value(1)),
When(engagement__gt=50, then=Value(2)),
default=Value(3),
output_field=IntegerField()
)
)
for article in res:
print(f"{article.title}: status {article.status}")
Результат выполнения кода:
"Popular Article 1: status 1"
"Popular Article 2: status 2"
"Regular Article 1: status 3"