Как определить свою агрегатную функцию в django orm

Я хочу определить агрегатную функцию, но не понимаю примера в документе Django toally.

Я буду ссылаться на пример, найденный в Django documentation.

Необходимо обратить внимание на разницу между аннотацией и агрегатом. Ан:

  1. Aggregate - это вычисление, которое происходит в базе данных, т.е. оно будет частью SQL-запроса. Он всегда возвращает dict a.k.a. key-value pair, где вы можете определить key имя, например
>>> Book.objects.aggregate(total_price_of_books=Sum('price'))
{'total_price_of_books': 1250.00}

или вы можете позволить Django определить имя, которое возвращает имя поля с двумя подчеркиваниями и используемую функцию, например

>>> Book.objects.aggregate(Sum('price'))
{'price__sum': 1250.00}

Обратите внимание: вы должны использовать имя существующего поля из вашей модели, например price или имя, которое вы создаете в аннотации (которую я объясню ниже) при использовании функций, например Sum, Avg, Min, Max и т.д.

  1. Аннотация - также происходит в базе данных, но всегда возвращает набор запросов. Они более сложные, поскольку их можно использовать для вычислений, а также для создания подзапросов, объединений SQL и более сложных запросов, что ускоряет процесс. Обычно аннотациям присваиваются имена, которые затем можно вызывать из возвращаемых объектов, например
  2. .
>>> pubs = Publisher.objects.annotate(number_of_books=Count('book'))

# This means it will count all the books that belong to each publisher in the set.

>>> <QuerySet [<Publisher: BaloneyPress>, <Publisher: SalamiPress>, ...]>
>>> pubs[0].number_of_books
73

Вы также можете использовать оба варианта. Скажем, например, вы хотите получить среднее значение самых высоких оценок для всех книг издательства BaloneyPress

>>> from django.db.models import Avg, Max
>>> Book.objects.filter(
      publisher__name='BaloneyPress'
    ).annotate(
      highest_rating=Max('rating')
    ).aggregate(
      average_rating=Avg('highest_rating')
    )
{'average_rating': 83.76}

# Or

>>> from django.db.models import Q
>>> highest_rating = Max('rating', filter=Q(publisher__name='BaloneyPress'))
>>> Book.objects.annotate(
      highest_rating=highest_rating
    ).aggregate(
      average_rating=Avg('highest_rating')
    )
{'average_rating': 83.76}

Что вы хотели бы сделать? Может быть, мы сможем заняться этим вместе.

Вернуться на верх