DJANGO - 按类别小计和按项目总计
DJANGO - Subtotal by category and total by item
晚上好!
假设我有一个数据库:
Category | Item | Price
Cat1 | Item1 |
Cat1 | Item2 |
Cat2 | Item3 |
Cat2 | Item3 |
Cat2 | Item4 |
我想按类别显示总销售额,并在按项目分组的销售明细下方显示
Cat1 - Total Price =
Item1 -
Item2 -
Cat2 - Total Price =
Item3 - (the sum of the two item3)
Item4 -
我几乎成功了,但我不知道如何按类别进行小计。
我的代码如下:
Model.py
class Category(models.Model):
Category= models.CharField(max_length=100)
class Item(models.Model):
Category= models.ForeignKey(Category, on_delete=models.CASCADE)
Item= models.CharField(max_length=100)
class Order(models.Model):
Category= models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
Item= models.ForeignKey(Item, on_delete=models.SET_NULL, null=True)
Price= models.DecimalField()
Views.py
def summary(request):
metrics = {
'total': Sum('Price'),
}
orders=Order.objects.values('Category','Item').annotate(**metrics))
Template.html
{% for order in orders%}
{% ifchanged order.Item%}
<tr>
<td>{{ order.Item}} </td>
<td>{{order.total}} </td>
</tr>
{% endifchanged %}
<tr>
<td>{{order.Item}}</td>
<td> {{order.total}}</td>
</tr>
{% endfor %}
您可以使用 Prefetch(..)
object [Django-doc] 对每个 Category
和每个 Item
进行聚合:
from django.db.models import Prefetch, Sum
def summary(request):
categories = Category.objects.annotate(
total=Sum('item__order__Price')
).prefetch_related(
Prefetch(
'item_set',
Item.objects.annotate(total=Sum('order__Price')),
to_attr='items_with_price'
)
)
return render(request, 'template.html', {'categories': categories})
在模板中,可以用以下方式渲染:
{% <b>for category in categories</b> %}
<tr>
<td><b>{{ category.Category }}</b></td>
<td><b>{{ category.total }}</b></td>
</tr>
{% <b>for item in category.items_with_price</b> %}
<tr>
<td>{{ item.Item }}</td>
<td>{{ item.total }}</td>
</tr>
{% endfor %}
{% endfor %}
晚上好!
假设我有一个数据库:
Category | Item | Price
Cat1 | Item1 |
Cat1 | Item2 |
Cat2 | Item3 |
Cat2 | Item3 |
Cat2 | Item4 |
我想按类别显示总销售额,并在按项目分组的销售明细下方显示
Cat1 - Total Price =
Item1 -
Item2 -
Cat2 - Total Price =
Item3 - (the sum of the two item3)
Item4 -
我几乎成功了,但我不知道如何按类别进行小计。 我的代码如下:
Model.py
class Category(models.Model):
Category= models.CharField(max_length=100)
class Item(models.Model):
Category= models.ForeignKey(Category, on_delete=models.CASCADE)
Item= models.CharField(max_length=100)
class Order(models.Model):
Category= models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
Item= models.ForeignKey(Item, on_delete=models.SET_NULL, null=True)
Price= models.DecimalField()
Views.py
def summary(request):
metrics = {
'total': Sum('Price'),
}
orders=Order.objects.values('Category','Item').annotate(**metrics))
Template.html
{% for order in orders%}
{% ifchanged order.Item%}
<tr>
<td>{{ order.Item}} </td>
<td>{{order.total}} </td>
</tr>
{% endifchanged %}
<tr>
<td>{{order.Item}}</td>
<td> {{order.total}}</td>
</tr>
{% endfor %}
您可以使用 Prefetch(..)
object [Django-doc] 对每个 Category
和每个 Item
进行聚合:
from django.db.models import Prefetch, Sum
def summary(request):
categories = Category.objects.annotate(
total=Sum('item__order__Price')
).prefetch_related(
Prefetch(
'item_set',
Item.objects.annotate(total=Sum('order__Price')),
to_attr='items_with_price'
)
)
return render(request, 'template.html', {'categories': categories})
在模板中,可以用以下方式渲染:
{% <b>for category in categories</b> %}
<tr>
<td><b>{{ category.Category }}</b></td>
<td><b>{{ category.total }}</b></td>
</tr>
{% <b>for item in category.items_with_price</b> %}
<tr>
<td>{{ item.Item }}</td>
<td>{{ item.total }}</td>
</tr>
{% endfor %}
{% endfor %}