Reputation: 65
I need to make a query, where I can display the total amount of clothes ordered by clients, the result should be like this:
Client_1 | Cloth_Type_X_SUM | Cloth_Type_Y_SUM | Cloth_Type_Z_SUM | SUM_ALL Client_2 | Cloth_Type_X_SUM | Cloth_Type_Y_SUM | Cloth_Type_Z_SUM | SUM_ALL Client_3 | Cloth_Type_X_SUM | Cloth_Type_Y_SUM | Cloth_Type_Z_SUM | SUM_ALL
models.py
class Cloth(models.Model):
description = models.CharField(max_length=30)
type = models.CharField(max_length=2)
class Order(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
class Order_Detail(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
cloth = models.ForeignKey(Cloth, on_delete=models.CASCADE)
weight = models.FloatField()
The closest that I got was:
Order_Detail.objects.values('order__client__name','cloth__type').annotate(Sum('weight'))
The problem with this is that it will retrieve an object for each cloth type:
Client_1 | Cloth_Type_X | SUM_X
Client_1 | Cloth_Type_Y | SUM_Y
Client_1 | Cloth_Type_Z | SUM_Z
Client_2 | Cloth_Type_X | SUM_X
Client_2 | Cloth_Type_Y | SUM_Y
Client_2 | Cloth_Type_Z | SUM_Z
Client_3 | Cloth_Type_X | SUM_X
Client_3 | Cloth_Type_Y | SUM_Y
Client_3 | Cloth_Type_Z | SUM_Z
Isn't there a better approach?
Upvotes: 0
Views: 512
Reputation: 6865
You can use Conditional Expressions
for that purpose
Order_Detail.objects.values('order__client').annotate(
cloth_type_x_sum = Sum(Case(When(cloth__type=X, then='weight'))),
cloth_type_y_sum = Sum(Case(When(cloth__type=Y, then='weight'))),
cloth_type_z_sum = Sum(Case(When(cloth__type=Z, then='weight'))),
).order_by('order__client')
Upvotes: 1
Reputation: 1983
from django.db.models import Sum
Order_Detail.objects.values('cloth').annotate(cloth_weight=Sum('weight'))
This will give you grouped by cloth type.
Order_Detail.objects.values('order__client').annotate(cloth_weight=Sum('weight'))
This will give yougrouped by client.
Upvotes: 0