2016-03-02 29 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, ...}