Donato Perconti
Donato Perconti

Reputation: 813

Adding Sum of Object Attributes to Django Rest Framework Response

I'm Trying to add the sum of multiple objects to a DRF response. For example, right now the response works with just listing the objects:

[
    {
        "id": "47d0deaa5c8c",
        "amount": "25.00"
    },
    {
        "id": "29787731",
        "amount": "25.00"
    }
]

But what I want is to be able to sum the amount attribute of those objects together and then include that in the response, so that it would look like this:

{  
   "sum":"50.00",
   "objects":[  
      {  
         "id":"47d0deaa5c8c",
         "amount":"25.00"
      },
      {  
         "id":"29787731",
         "amount":"25.00"
      }
   ]
}

Here's my current APIView:

class TransactionsList(GenericAPIView):
"""
Retrieve list of transactions
"""

authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)

def get(self, request):
    """List Transactions"""
    transaction = Transaction.objects.all()
    serializer = TransactionSerializer(transaction, many=True)
    return Response(serializer.data)

And Serializer:

class TransactionSerializer(serializers.ModelSerializer):

class Meta:
    model = Transaction
    fields = ('id', 'amount')

How could I efficiently go about adding the sum field into the response?

Upvotes: 1

Views: 3474

Answers (2)

Ykh
Ykh

Reputation: 7717

change

return Response(serializer.data)

to

from django.db.models import Sum
all_sum = transaction.aggregate(Sum('amount'))['amount__sum']
return Response({'sum': all_sum if all_sum else 0 , 'objects': serializer.data})

Upvotes: 3

JPG
JPG

Reputation: 88569

Since the amount field seems string type. So, we've to convert to int before summing them.

class TransactionsList(GenericAPIView):
    """
    Retrieve list of transactions
    """
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def get(self, request):
        """List Transactions"""
        transaction = Transaction.objects.all()
        serializer = TransactionSerializer(transaction, many=True)
        return_data = {"sum": str(sum([lambda items: int(items['amount'])])), "objects": serializer.data}
        return Response(return_data)


If the amount field is int type, then you don't want to add do the type casting. If so, use this,

return_data = {"sum": sum([lambda items: items['amount']]), "objects": serializer.data}

Upvotes: 1

Related Questions