我在商店中保存每件商品。我希望使用聚合来汇总每个商店一个月内的所有销售额。我想过滤达到目标的商店(100.000 $)。
我已经提出了使用python和列表的解决方案。但我想知道是否有更好的解决方案只使用ORM。
Sales model
Store Sale Date
Store A 5.000 11/01/2014
Store A 3.000 11/01/2014
Store B 1.000 15/01/2014
Store C 8.000 17/01/2014
...
结果应该是这样的:
Month: January
Store Amount
A 120.000
B 111.000
C 150.000
and discard
D 70.000
感谢您的帮助。
答案 0 :(得分:3)
其他建议的方法会丢弃大量需要几分之一秒加载的数据,这在以后的代码中可能会有用。因此这个答案。
您可以查询Sales
对象,而不是查询Store
对象。除了关系之外,查询大致相同:
from django.db.models import Sum
stores = Store.objects.filter(sales__date__month=month, sales__date__year=year) \
.annotate(montly_sales=Sum('sales__amount')) \
.filter(montly_sales__gte=100000) \
# optionally prefetch all `sales` objects if you know you need them
.prefetch_related('sales')
>>> [s for s in stores]
[
<Store object 1>,
<Store object 2>,
etc.
]
所有Store
个对象都有一个额外的属性montly_sales
,该属性具有该特定月份的总销售额。通过在注释之前过滤月份和年份,注释仅使用过滤的相关对象。请注意,商店中的sales
属性仍包含该商店的所有销售额。
使用此方法,您可以轻松访问所有商店属性,这与使用.values
对结果进行分组时不同。
答案 1 :(得分:2)
如果没有好好看看你的模型,我能做的最好的就是伪代码。但我希望你需要的东西是
from django.db.models import Sum
results = Sales.objects.filter(date__month=month, date__year=year)
results = results.values('store')
results = results.annotate(total_sales=Sum(sale))
return results.filter(total_sales__gt=100)
基本上,我们正在做的是使用django的聚合功能来计算每个商店的销售总额。根据django&#39; documentation,我们可以使用values
函数按给定字段中的不同值对结果进行分组。
total_sales
大于100的商店。答案 2 :(得分:0)
您可以使用annotate
来处理此问题。由于我不知道你的模型结构,这是一个平均猜测
from djnago.db.models import Sum
Sales.objects.filter(date__month=3, date__year=2014).values('store').annotate(monthly_sale=Sum('sale'))
这将返回一个商店的查询集及其月销售额,如:
>> [
{"store": 1, "monthly_sale": 120.000},
{"store": 2, "monthly_sale": 100.000},
...
]
在上面的查询中假设你有:
Date
Datetime
或date
字段
Sale
模型与Store
Sales
模型有一个名为Integer
Decimal
,sale
等)
在生成的QuerySet中,store
是商店记录的ID。但由于它是ForeigKey,你可以使用关系来获取它的名字......
Sales.objects.filter(date__month=3, date__year=2014).values('store__name').annotate(monthly_sale=Sum('sale'))
>> [
{"store__name": "Store A", "monthly_sale": 120.000},
{"store__name": "Store B", "monthly_sale": 100.000},
...
]