Как определить свою агрегатную функцию в django orm
Я хочу определить агрегатную функцию, но не понимаю примера в документе Django toally.
Я буду ссылаться на пример, найденный в Django documentation.
Необходимо обратить внимание на разницу между аннотацией и агрегатом. Ан:
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 и т.д.
- Аннотация - также происходит в базе данных, но всегда возвращает набор запросов. Они более сложные, поскольку их можно использовать для вычислений, а также для создания подзапросов, объединений SQL и более сложных запросов, что ускоряет процесс. Обычно аннотациям присваиваются имена, которые затем можно вызывать из возвращаемых объектов, например .
>>> 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}
Что вы хотели бы сделать? Может быть, мы сможем заняться этим вместе.