Как аннотировать связанный объект с MAX по некоторому атрибуту

class Bill
    number = CharField

class Service
    number = CharField
    bill = ForeignKey(Bill, related_name="bill_services")
    price = IntegerField

bills = Bill.objects.prefetch_related('bill_services').annotate(service_number_with_max_price=....)

Здравствуйте. Как я могу аннотировать услугу number с максимальной ценой для каждого счета. Я хочу использовать его для чего-то вроде этого:

{% for bill in bills %}
    {{ bill.service_number_with_max_price }}
{% endfor %}

Вы можете использовать агрегатный метод.

from django.db.models import Max

query = Bill.objects.all().prefetch_related("bill_services").aggregate(max_price=Max("bill_services__price"))

В шаблоне вы можете получить доступ к максимальной цене услуги по

{% for bill in bills %}
    {{ bill.max_price }}
{% endfor %}

Вы можете аннотировать подзапрос для этого:

from django.db.models import OuterRef, Subquery

subquery = Service.objects.filter(bill=OuterRef('pk')).order_by('-price').values('number')[:1]
bills = Bill.objects.prefetch_related('bill_services').annotate(service_number_with_max_price=Subquery(subquery))

Подзапрос делает следующее для достижения вашего варианта использования:

  1. .filter(bill=OuterRef('pk')): Получает Service объекты с внешним ключом к текущей строке внешних запросов.
  2. .order_by('-price'): Упорядочивает результаты в порядке убывания цены.
  3. .values('number'): Выбирает только поле number.
  4. [:1]: Ограничить результаты одним рядом для подзапроса.
  5. .
Вернуться на верх