我正在尝试对我的模型执行分组,如下所示:
class Restaurant(models.Model):
pass
class Order(models.Model):
created = models.DateTimeField(auto_now_add=True)
restaurant = mdoels.ForeignKey('Restaurant')
现在我想知道每天创建了多少订单。这意味着我需要从DateTime字段获取日期,然后计数。
如果相关,我会以这种方式获取Order
查询集:
restaurant = Restaurant.objects.get(id=request.data['restaurant_id'])
orders = restaurant.order_set.filter(created__lte=some_date)
现在,我怎样才能从orders
得到我想要的东西?我尝试过这样的事情:
orders.values('created').annotate(Count('created'))
使用TruncDate
等等。
我正在使用Python 2和Django 1.11。
编辑更好地表达我的意图。我希望在纯python中实现一些类似这样的东西:
orders_by_date = {}
for order in orders:
if orders_by_date.get(datetime.date(orders[0].created.year, orders[0].created.month, orders[0].created.day):
orders_by_date[datetime.date(orders[0].created.year, orders[0].created.month, orders[0].created.day)] += 1
else:
orders_by_date[datetime.date(orders[0].created.year, orders[0].created.month, orders[0].created.day)] = 1
EDIT2 我能够成功显示单个日期的计数:
orders.filter(created__date=datetime.date(2018, 6, 8)).aggregate(Count('id'))
给我{'id__count': 3}
。现在按所有日期分组是完美的,而不仅仅是这一个。
答案 0 :(得分:1)
您应该可以执行[{'id__count': 3},{'id__count': 1},...]
,这会为您提供一个词典列表:orders_with_counts = orders.annotate(Count('id'))
dates_and_counts = orders_with_counts.values_list('created__date','id__count')
dct = dict(dates_and_counts)
。
以下是docs
编辑: 尝试注释然后获取值:
dates_and_counts
[(date1,count1),(date2,count2)...]
将是元组列表:dct
。 =OR(SUMPRODUCT(--(Table1[OM]=[@OM]),--(Table1[F]=[@F])),SUMPRODUCT(--(Table2[OM]=[@OM]),--(Table2[F]=[@F])))
将被转换为字典。
答案 1 :(得分:0)
您可以使用以下命令在一个查询中获取数据:
from django.db.models import DateField, Sum
from django.db.models.functions import Cast
query = Order.objects.filter(
restaurant=some_restaurant
).annotate(
create_date=Cast('created', DateField())
).values('create_date').annotate(
id_count=Count('id')
).order_by('create_date')
这将返回QuerySet
字典,如:
<QuerySet [{'create_date': datetime.date(2017, 1, 31), 'id_count': 14},
{'create_date': datetime.date(2017, 2, 2), 'id_count': 25},
{'create_date': datetime.date(2017, 2, 9), 'id_count': 13},
{'create_date': datetime.date(2017, 2, 10), 'id_count': 2},
{'create_date': datetime.date(2017, 2, 16), 'id_count': 17},
{'create_date': datetime.date(2017, 2, 17), 'id_count': 89},
{'create_date': datetime.date(2017, 2, 20), 'id_count': 20},
{'create_date': datetime.date(2017, 2, 23), 'id_count': 18},
{'create_date': datetime.date(2017, 2, 24), 'id_count': 20},
{'create_date': datetime.date(2017, 2, 28), 'id_count': 20},
{'create_date': datetime.date(2017, 3, 1), 'id_count': 3},
{'create_date': datetime.date(2017, 3, 3), 'id_count': 9},
{'create_date': datetime.date(2017, 3, 7), 'id_count': 9},
{'create_date': datetime.date(2017, 3, 9), 'id_count': 1},
{'create_date': datetime.date(2017, 3, 10), 'id_count': 7},
{'create_date': datetime.date(2017, 3, 14), 'id_count': 2},
{'create_date': datetime.date(2017, 3, 15), 'id_count': 7},
{'create_date': datetime.date(2017, 3, 17), 'id_count': 9},
{'create_date': datetime.date(2017, 3, 22), 'id_count': 2},
{'create_date': datetime.date(2017, 3, 24), 'id_count': 8},
'...
(remaining elements truncated)...']>
(添加格式)
在幕后,它会生成如下查询:
SELECT CAST(`order`.`created` AS date) AS `create_date`,
COUNT(`order`.`id`) AS `id_count`
FROM `order`
WHERE `order`.`restaurant_id` = 123
GROUP BY CAST(`order`.`created` AS date)
ORDER BY `create_date` ASC
(其中123
在这里是一个样本餐馆ID。)
因此,您可以例如迭代结果并构造JSON对象等。
我们可以将其翻译成一个字典,通过使用字典理解迭代查询来将datetime.date
个对象映射到计数:
result = { t['create_date']: t['id_count'] for t in query }
请注意,没有任何Order
的日期不会成为查询集的一部分(也不是result
字典的一部分,这是合乎逻辑的,因为我们将Order
表作为“root”,如果没有行,则没有输出)