Отображение значения суммы вложенного объекта в сериализаторе

У меня есть приложение, в котором пользователи вводят свои ежедневные расходы и доходы. Данные API выглядят следующим образом

  [{
        "id": "07cf140c-0d4d-41d7-9a31-ac0f5f456840",
        "owner": 2,
        "entry": [
            {
                "id": 1,
                "owner": 1,
                "title": "aa",
                "amount": 22,
                "description": "za pizze",
                "entry_type": "income",
                "date_added": "2022-08-13",
                "entry_category": 1
            }
        ],
        "viewable": [
            1,
            2
        ],
        "name": "as",
        "date_added": "2022-08-13"
    },
    {
        "id": "d458196e-49f1-42db-8bc2-ee1dba438953",
        "owner": 1,
        "entry": [
            {
                "id": 1,
                "owner": 1,
                "title": "aa",
                "amount": 22,
                "description": "za pizze",
                "entry_type": "income",
                "date_added": "2022-08-13",
                "entry_category": 1
            },
            {
                "id": 2,
                "owner": 1,
                "title": "sas",
                "amount": 323,
                "description": "stacja",
                "entry_type": "expenses",
                "date_added": "2022-08-13",
                "entry_category": 5
            }
        ],
        "viewable": [],
        "name": "dsdsds",
        "date_added": "2022-08-13"
    }]

А я знаю, как суммировать поле суммы, чтобы получить сумму доходов/расходов

    def get_queryset(self):
        user_id = self.request.user.id
        available = BudgetEntry.objects.filter(
            Q(owner=user_id) 
        )
        a = available.filter(entry_type='income').aggregate(Sum('amount'))['amount__sum']
        print(a)
        return available

но как я могу получить эти данные для отображения непосредственно в JSON? Таким образом, чтобы их можно было использовать повторно. потому что я хочу также получить топ категорий, в которых пользователь тратит или экономит больше всего

Serializers.py

class CategorySerializer(serializers.ModelSerializer):

    class Meta:
        model = Category
        fields = ('name',)

class BudgetEntrySerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.id')

    class Meta:
        model = BudgetEntry
        fields = '__all__'

class WalletInstanceSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.id')
    entry = BudgetEntrySerializer(many=True, read_only=True)
    viewable = serializers.PrimaryKeyRelatedField(queryset=get_user_model().objects.all(), many=True)

    class Meta:
        model = WalletInstance
        fields = '__all__'

Виды

class WalletViewset(viewsets.ModelViewSet):
    permission_classes = [IsAuthenticated]
    serializer_class = WalletInstanceSerializer
    filterset_class = WalletFilter

    def get_queryset(self):
        user_id = self.request.user.id

        available = WalletInstance.objects.filter(
            Q(owner=user_id) |
            Q(viewable = user_id) 
        ).distinct()
        return available

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

class BudgetEntryViewset(viewsets.ModelViewSet):
    permission_classes = [IsAuthenticated]
    serializer_class = BudgetEntrySerializer
    filterset_class = BudgetFilter

    def get_queryset(self):
        user_id = self.request.user.id
        available = BudgetEntry.objects.filter(
            Q(owner=user_id) 
        )
        a = available.filter(entry_type='income').aggregate(Sum('amount'))['amount__sum']
        print(a)
        return available

Модели

class BudgetEntry(models.Model):
    STATE= [
        ('income','income'),
        ('expenses','expenses'),
    ]
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='owner_of_entry', on_delete=models.CASCADE)
    title = models.CharField(max_length=20)
    amount = models.IntegerField()
    description = models.CharField(max_length=60, null=True)
    entry_type = models.CharField(max_length=15, choices=STATE, null=True)
    entry_category = models.ForeignKey(Category, null=True, blank=True, related_name='category_of_entry', on_delete=models.SET_NULL)
    date_added = models.DateField(auto_now_add=True)



class WalletInstance(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
    name = models.CharField(max_length=30, null=True)
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='owner', on_delete=models.CASCADE)
    viewable = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='can_view', blank=True)
    entry = models.ManyToManyField(BudgetEntry, related_name='BudgetEntry', blank=True)
    date_added = models.DateField(auto_now_add=True)

Пример конечного результата

  [{
        "id": "07cf140c-0d4d-41d7-9a31-ac0f5f456840",
        "owner": 2,
        "entry": [
            {
                "id": 1,
                "owner": 1,
                "title": "aa",
                "amount": 22,
                "description": "za pizze",
                "entry_type": "income",
                "date_added": "2022-08-13",
                "entry_category": 1
            }
        ],
        "viewable": [
            1,
            2
        ],
        "name": "as",
        "date_added": "2022-08-13"
    },
    {
        "id": "d458196e-49f1-42db-8bc2-ee1dba438953",
        "owner": 1,
        "entry": [
            ....
        ],
        "viewable": [],
        "name": "dsdsds",
        "date_added": "2022-08-13",
        "sum_income": 123
        "sum_expense":234
        "top_category": 2
    }]
Вернуться на верх