Как использовать Django аннотировать? - PullRequest
1 голос
/ 16 февраля 2020

Я хотел бы спросить, как я могу сократить это до одной команды? Я понимаю, что annotete является правильным способом сделать это, но не понимаю, как.

Вот мой код, который слишком медленный:

sum = 0
for contact in self.contacts.all():
   sum += (contact.orders.aggregate(models.Sum('total'))['total__sum'])
return sum

I Хотелось бы получить Сумма для каждого контакта, все записи в итоговом столбце соответствующих заказов.

Приведенный выше код дает сумму, но вяло медленно. Я понимаю, что это можно сделать с помощью аннотации, но не знаю, как ее использовать.

Вот контакт:

class Contact(models.Model):
    company = models.ForeignKey(
        Company, related_name="contacts", on_delete=models.PROTECT)
    first_name = models.CharField(max_length=80)
    last_name = models.CharField(max_length=80, blank=True)
    email = models.EmailField()

А вот заказы:

class Order(models.Model):
    order_number = models.CharField(max_length=80)
    company = models.ForeignKey(Company, related_name="orders")
    contact = models.ForeignKey(Contact, related_name="orders")
    total = models.DecimalField(max_digits=12, decimal_places=6)
    order_date = models.DateTimeField(null=True, blank=True)

Помогите пожалуйста

1 Ответ

1 голос
/ 16 февраля 2020

Вы можете аннотировать ваш набор запросов на модели Contract с помощью:

from django.db.models import <b>Sum</b>

Contract.objects.annotate(
    <b>total_orders=Sum('orders__total')</b>
)

Contract объектов, которые возникают из этого набора запросов, будет иметь дополнительный атрибут .total_orders, который содержит сумму поля total связанных Order объектов.

Таким образом, будет создан запрос, который выглядит следующим образом:

SELECT contract.*, <b>SUM(order.total)</b>
FROM contract
LEFT OUTER JOIN order ON order.contract_id = contract.id
<b>GROUP BY contract.id</b>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...