'Using Multiple Annotations in Django

Here is my data base:

class User(models.Model):
   Name = models.TextField(null=True, blank=True, default=None)

class Salary(models.Model):
   value = models.PositiveIntegerField(default=1)
   name = models.ForeignKey(User, related_name='salarys', on_delete=models.CASCADE)

class Expense(models.Model):
   value = models.PositiveIntegerField(default=1)
   name = models.ForeignKey(User, related_name='expenses', on_delete=models.CASCADE)

I want to add all the salary and expenses of a user. 

queryset = User.objects.annotate(total_salary=Sum('salarys__value', distinct=True) ,total_expense=Sum('expenses__value', distinct=True))

Here is my data:

User table
id=1; name= ram

Salary table
id =1; value = 12000
id = 2; value = 8000

Expense table
id =1; value=5000
id=2; value = 3000

expected output : total_Salary = 20000; total_expense=8000 output

obtained : total_salary= 40000; total_expense = 16000

Every output is multiplied the number of times the data in another table. Can anyone help me through this



Solution 1:[1]

Can you try this ?

queryset = User.objects.all().annotate(total_salary=Sum('salarys__value') ,total_expense=Sum('expenses__value'))

Solution 2:[2]

looks like it is not possible if you are trying to combine like aggregates. Only works for Count with distinct. For closure, please refer to docs: https://docs.djangoproject.com/en/4.0/topics/db/aggregation/#combining-multiple-aggregations

Since annotate returns a queryset instead of a dict(in case of aggregate), you can try chaining multiple like values().annotate("field1").annotate("field2"). Worked for me, though please check sql from your queryset to debug in case you cannot run your query as desired.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2