РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
156 of 818 menu

Класс Subquery

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

Синтаксис

Subquery(queryset, output_field=None, **extra)

Параметры:

  • queryset - объект QuerySet, который будет выполнен как подзапрос. Должен возвращать одно значение или одну колонку.
  • output_field - опциональный параметр, указывающий тип поля для результата подзапроса.

Пример

Используем Subquery для получения количества комментариев к каждой статье:

from django.db.models import Subquery, Count, OuterRef from myapp.models import Article, Comment subquery = Comment.objects.filter(article=OuterRef('pk')).values('article').annotate( total=Count('pk') ).values('total') articles = Article.objects.annotate(comments_count=Subquery(subquery)) for article in articles: print(f"{article.title}: {article.comments_count}")

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

"article 1: 5" "article 2: 3" "article 3: 0"

Пример

Фильтрация статей по самому позднему комментарию с использованием Subquery и агрегации:

from django.db.models import Subquery, Max, OuterRef from myapp.models import Article, Comment from datetime import datetime subquery = Comment.objects.filter( article=OuterRef('pk') ).values('article').annotate( last_date=Max('created_at') ).values('last_date') recent_articles = Article.objects.filter( id__in=Subquery( Comment.objects.filter( created_at__gte=datetime(2025, 1, 1) ).values('article') ) ) for article in recent_articles: print(article.title)

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

"article 1" "article 3"

Пример

Сравнение значения поля с результатом подзапроса с помощью Subquery в фильтрации:

from django.db.models import Subquery, F, OuterRef from myapp.models import Product, Order subquery = Order.objects.filter( product=OuterRef('pk') ).values('product').annotate( total_sum=Sum('quantity') ).values('total_sum') products = Product.objects.annotate( ordered_count=Subquery(subquery) ).filter( ordered_count__gt=F('stock') ) for product in products: print(f"{product.name}: {product.ordered_count}")

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

"product 1: 15" "product 3: 8"

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

  • класс OuterRef,
    который используется для ссылки на внешний запрос внутри подзапроса
  • класс Exists,
    который проверяет существование записей в подзапросе
  • метод annotate,
    который добавляет вычисляемые поля к каждой записи QuerySet
  • метод filter,
    который применяет условия фильтрации к QuerySet
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить