Django ORM-группа по расчету должна возвращать данные, если у сторонних тоже нет связанных данных - PullRequest
2 голосов
/ 05 мая 2020

Это мои модели:

class Purchase(models.Model):
    amount = models.DecimalField(
        max_digits=6,
        decimal_places=2,
        default=0.00
    )
    entry_for = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='ledger_entry_for',
    )

Например, у меня 400+ пользователей, но только 50 пользователей совершали покупки несколько раз

Так что я хочу, чтобы общая сумма покупок использовалась пользователем.

, так что это мой запрос ниже:

purchase_user_wise = Purchase.objects.values(
            'entry_for'
        ).annotate(
            total_purchase=Sum('amount')
        )

Вышеупомянутый запрос работает нормально, и я возвращаю общее количество пользователей за пользователем, но проблема в том, что он возвращает только расчет тех пользователей, которые приобрели хотя бы один раз или более одного раза. и этот запрос не возвращает данные всех 400 пользователей.

Я хочу, чтобы если у кого-то из пользователей нет записи о покупке, он должен вернуть 0, и остальные вычисления должны работать таким образом.

Кто-нибудь может мне помочь, как я могу это сделать?

1 Ответ

2 голосов
/ 05 мая 2020

Вы должны сделать это наоборот: запросить из объекта User и аннотировать пользователей:

from django.db.models import Sum

User.objects.annotate(
    <b>total_purschase=Sum('ledger_entry_for__amount')</b>
)

Это вернет набор запросов из User объектов, и каждый User из этого запроса будет иметь дополнительный атрибут .total_purchase.

Если пользователь не совершил покупки, то сумма будет None (NULL). Вы можете использовать выражение Coalesce [Django -doc] , чтобы использовать вместо 0:

from django.db.models import Sum, <b>Value</b>
from django.db.models.functions import <b>Coalesce</b>

User.objects.annotate(
    total_purschase=<b>Coalesce(</b>Sum('ledger_entry_for__amount')<b>, Value(0))</b>
)
...