Метод alias

Метод alias применяется к QuerySet и добавляет выражение в запрос, присваивая ему псевдоним. Этот псевдоним может быть использован в других частях запроса, например, в annotate или order_by. В отличие от annotate, метод alias не добавляет выражение в результаты выборки.

Синтаксис

pythonModel.objects.alias(**expressions)

Метод принимает один или несколько именованных аргументов, где имя становится псевдонимом, а значение - выражением для вычисления.

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

Допустим, у нас есть модель статьи:

pythonfrom 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 для сортировки статей по популярности:

pythonfrom 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}")

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

python"Popular Article 1: 150"
"Popular Article 2: 120"
"Popular Article 3: 80"

Пример . С filter и annotate

Покажем, как использовать alias вместе с annotate для фильтрации по вычисляемому полю:

pythonfrom 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}")

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

python"Django Article: 13"
"Learn Django: 11"

Пример . С аннотацией

Метод alias может быть полезен для создания промежуточных вычислений:

pythonfrom 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}")

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

python"Popular Article 1: status 1"
"Popular Article 2: status 2"
"Regular Article 1: status 3"

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

  • метод annotate,
    который добавляет вычисляемые поля в результаты запроса
  • метод order_by,
    который сортирует QuerySet по указанным полям
  • метод filter,
    который фильтрует записи в QuerySet по заданным условиям
  • метод values,
    который возвращает QuerySet словарей вместо объектов