Я пытаюсь вычислить эквивалент SELECT SUM(...) FROM ... GROUP BY ...
. Вот упрощенная аналогия:Возможно ли объединение по агрегированному запросу с помощью django ORM?
Скажем Salesperson
объекты продают вещи и получить комиссию на полях они производят через каждый Sale
:
sp = Salesperson.objects.get(pk=1)
my_sales = Sale.objects.filter(fk_salesperson=sp)
#calculate commission owing to sp
commission = 0
for sale in my_sales:
commission += sp.commission_rate\
* (sale.selling_price - sale.cost_price)
Этот последний цикл может быть сделано что-то вроде:
.annotate(commission= (F('selling_price')-F('cost_price'))\
* sp.commission_rate)
Но могу ли я затем агрегировать запрос для всех объектов Salesperson
? То есть Я хочу знать каждую комиссию продавца (т. Е. Примерно SELECT SUM((sale_price-cost_price) * commission_rate) FROM Sales GROUP BY Salesperson
). Я мог бы сделать что-то вроде ниже, но я пытаюсь сделать это с ОРМ:
commissions = []
salespeople = Salesperson.objects.all()
for sp in salespeople:
data = Sale.objects.filter(fk_salesperson=sp)\
.annotate(salesperson=F('sp__email')\
.annotate(commission= (F('selling_price')-F('cost_price'))\
* sp.commission_rate)
commissions.append(data)
Есть ли способ сделать это с помощью одного запроса (что делает сервер отчетов дб сделать работу), а не делать это на моем сервере приложений?
Спасибо, Unfortuneately ваше решение не понимает сути примера question.The намеренно построено таким образом, что не существует связанное с поля «' sales'»в модели' Salesperson'. (Это логично: продажа должна быть иностранным ключом, указывающим на продавца, а не наоборот). Цель этого примера - найти решение для запроса в 'Sale', а затем группировать по внешнему ключу соответствующего поля в' Sale' под названием '' fk_salesperson'. – Escher
Там ** есть ** отношение, хотя и неявное. Это обратное отношение. https://docs.djangoproject.com/en/1.9/topics/db/queries/#backwards-related-objects –
Я бы рекомендовал установить ['related_name'] (https://docs.djangoproject.com/en /1.9/ref/models/fields/#django.db.models.ForeignKey.related_name) для каждого ForeignKey, чтобы дать ему значимое имя. Если вы его не установили, я думаю, что это будет 'sale_set__' вместо' sales__'. –