Django Aggreagtion: только возвращаемое значение суммы?

У меня есть список оплаченных значений, и я хочу отобразить общее количество оплаченных. Я использовал Агрегацию и Сумму, чтобы вычислить значения вместе. Проблема в том, что я просто хочу, чтобы общая стоимость была распечатана, а агрегация распечатана: {'amount__sum': 480.0} (480.0 - общая добавленная стоимость.

На мой взгляд, у меня есть:

    from django.db.models import Sum

    total_paid = Payment.objects.all.aggregate(Sum('amount'))

И чтобы показать значение на странице, у меня есть шаблон мако со следующим:

    <p><strong>Total Paid:</strong> ${total_paid}</p>

Как мне заставить это показать 480.0 вместо {'amount__sum': 480.0}?

6 ответов

Решение

Я не верю, что есть способ получить только ценность.

Вы могли бы просто сделать ${{ total_paid.amount__sum }} в вашем шаблоне. Или сделать total_paid = Payment.objects.all().aggregate(Sum('amount')).get('amount__sum', 0.00) по вашему мнению.

РЕДАКТИРОВАТЬ

Как уже отмечали другие, .aggregate() всегда будет возвращать словарь со всеми ключами из имеющихся агрегатов, поэтому .get() на результат не надо. Однако, если набор запросов пуст, каждое статистическое значение будет None, Таким образом, в зависимости от вашего кода, если вы ожидаете float, вы можете сделать:

total_paid = Payment.objects.all().aggregate(Sum('amount'))['amount__sum'] or 0.00

Дайте ему имя, а затем спросите его:

total_paid = Payment.objects.all.aggregate(sum=Sum('amount'))['sum']

Должно быть немного более читабельным, и нет необходимости в преобразовании.

aggregate() Метод возвращает словарь. Если вы знаете, что вы возвращаете словарь только для одной записи, вы можете использовать .values()[0],

В Python 2:

total_paid = Payment.objects.aggregate(Sum('amount')).values()[0]

В Python 3(спасибо @lmiguelvargasf) это должно быть:

total_paid = list(Payment.objects.aggregate(Sum('amount')).values())[0]

Конечный результат совпадает с ответом @jproffitt, но избегает повторения amount__sum часть, так что это немного более общее.

В Python 3:

Вы можете решить это путем преобразования dict_values к list:

total_paid = list(Payment.objects.aggregate(Sum('amount')).values())[0] or 0 # the or 0 is required in case the query is an empty query set.

Предыдущий код избегает использования 'column_name__sum' в качестве ключа, но если вы предпочитаете словарь:

total_paid = Payment.objects.aggregate(Sum('amount'))['amount__sum'] or 0

С точки зрения эффективности, я сделал тест с некоторыми данными, которые у меня есть, и кажется, что использование словарного ключа быстрее:

In [9]: %timeit total = Pledge.objects.filter(user=user, group__isnull=True).aggregate(Sum('amount'))['amount__sum'] or 0
3.13 ms ± 25.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [10]: %timeit total = list(Pledge.objects.filter(user=user, group__isnull=True).aggregate(Sum('amount')).values())[0] or 0
3.22 ms ± 61.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

С точки зрения читабельности, я думаю, что решение @mehmet является лучшим, и я также проверил его эффективность:

In [18]: %timeit Pledge.objects.filter(user=user, group__isnull=True).aggregate(sum=Sum('amount'))['sum'] or 0
3.22 ms ± 124 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

(Это полезно, только если вы использовали десятичное поле). Сохраните значение ключа в новой переменной и преобразуйте его в число с плавающей запятой, если вы используете десятичное. Я думаю это самый простой способ

total_paid = Payment.objects.all.aggregate(Sum('amount'))
# output: {'amount__sum':Decimal('0000.000000')
tp=total_paid['amount__sum']
new_total_paid=float(tp)

На 100% вы можете удовлетворить ваши потребности с помощью этой техники

      from django.db.models import Sum
sum_count = Payment.objects.aggregate(Sum('amount'))
totalAmonut = sum_count['Qty__sum']
Другие вопросы по тегам