i'm using this queryset for my requirements
invoices = Invoice.objects.aggregate(total_amount=Sum('order__order_items__amount'),number_of_invoices=Count('pk', distinct=True))
which returns dict--->
{'total_amount': Decimal('17700.00'), 'number_of_invoices': 2}
but I want queryset how can i do that.. Thanks for any help
CodePudding user response:
This is what aggregate do :)
You can add a DecimalField
to Invoice
model, that aggregates total_amount
during before every save. I suggest signals for that.
apps.py
class YourAppConfig(AppConfig):
...
def ready(self):
from . import signals
signals.py
from django.db.models.signals import pre_save
from django.dispatch import receiver
from .models import Invoice
@receiver(pre_save, sender=Invoice)
def total_amount_aggregation(sender, instance, *args, **kwargs):
instance.total_amount = # aggregate desired amount here
You have to set similar signals for your Order
, so if you change Order
object, the related Invoice
object will be recalculated.
After that QuerySet
will stay as QuerySet
and every object will have always caclulated field.
CodePudding user response:
Instead of using .aggregate(...)
use .annotate(...)
this will return a QuerySet with given expression
from django.db.models import Sum, Count
invoices = Invoice.objects.annotate(
total_amount=Sum('order__order_items__amount'),
number_of_invoices=Count('pk', distinct=True)
)
then to get Sum(...)
& Count(...)
of field then do like this invoices[0].total_amount__sum
& invoices[0].number_of_invoices__count