2016-03-02 68 views
1

我有这样的表名为Orders每一个订单具有状态,我想重要的结果基于状态:Django的ORM计数返回结果只有一个

status_counts = Order.objects.all().values('status').annotate(
    pending = Count(Case(
     When(status__exact = Order.STATUS_PENDING, then = F('pk')) 
    )), 
    completed = Count(Case(
     When(status__exact = Order.STATUS_COMPLETED, then = F('pk')) 
    )), 
    failed = Count(Case(
     When(status__exact = Order.STATUS_FAILED, then = F('pk')) 
    )), 
    reversed = Count(Case(
     When(status__exact = Order.STATUS_REVERSED, then = F('pk')) 
    ))) 

我查询的问题是,它返回导致对各状态:

[{'completed': 4571, 'pending': 0, 'failed': 0, 'reversed': 0, 'status': 0}, {'completed': 0, 'pending': 2278, 'failed': 0, 'reversed': 0, 'status': 1}, {'completed': 0, 'pending': 0, 'failed': 0, 'reversed': 353, 'status': 3}]

有没有一种方法,我可以有这样的结果:

{'completed': 4571, 'pending': 2278, 'failed': 0, 'reversed': 353, 'status': 0}

+0

除非这是在一个高容量的要求使用,我肯定会推荐在一系列这样做不同的'count'查询。虽然效率不高,但推理起来要容易得多,无论是谁维护这些代码甚至是下一次阅读 - 即使是你,从现在开始的一个月 - 也一定能够更好地解释它。 – kungphu

回答

0

检查以下几项工作:

dict(Order.objects.all().values('status').annotate(scount=Count('status')).values_list('status', 'scount')) 

其分解

# get all available statuses 
qs = Order.objects.all().values('status') 

# annotate each status with count 
qs = qs.annotate(scount=Count('status')) 
# [{'status': 'completed', 'scount': 4571}, {'status': 'pending', 'scount': 2278} ...] 

# now get only what you want in `values_list` 
qs = qs.values_list('status', 'scount') 
# [('completed', 4571), ('pending', 2278), ...] 

# and then convert it to dict 
result = dict(qs) 
# {'completed': 4571, 'pending': 2278, ...}