以前的orm的group by方法在django 1.8 中已經不能使用,須要利用annotate來實現python
第一個values用來選中須要用來group by的字段(此處group by user_id),以後緊跟annotate來分組並聚合須要的字段(須要每一個user_id對應的question_id的數量和catalog_id的最小值),以後再values來實際查詢須要的字段(原user_id和聚合後的字段的別名)mysql
第一個values用來指定用來group by的字段,裏面必須是Count、Min等等聚合函數(例如用F("user_id")取別名是不行的),不須要最終查詢的就沒必要聚合了sql
第二個values用來指定實際select的字段,只能指定annotate後的字段名(以此處爲例:user_id是用來分組的字段,能夠直接取,而其餘字段必須聚合並使用聚合後的別名,qid和cid,假如原表還有個字段status,annotate中沒有聚合此字段,因此最後value不能查詢該字段)django
q = PxbNCEUserQuest.objects.filter(user_id=335).values("user_id").annotate(qid=Min("question_id"), cid=Min("catalog_id")).values("user_id", "qid", "cid") print q print q.query # 輸出 [{'qid': 22, 'user_id': 335L, 'cid': 17}] SELECT `pxb_nce_user_quest`.`user_id`, MIN(`pxb_nce_user_quest`.`question_id`) AS `qid`, MIN(`pxb_nce_user_quest`.`catalog_id`) AS `cid` FROM `pxb_nce_user_quest` WHERE `pxb_nce_user_quest`.`user_id` = 335 GROUP BY `pxb_nce_user_quest`.`user_id` ORDER BY NULL
q = PxbNCEUserQuest.objects.filter(user_id=335).values("user_id").annotate(qid=Min("question_id"), cid=Min("catalog_id")).annotate(uid=F("user_id")).values("uid", "qid", "cid") print q print q.query # 輸出: [{'qid': 22, 'uid': 335L, 'cid': 17}] SELECT MIN(`pxb_nce_user_quest`.`question_id`) AS `qid`, MIN(`pxb_nce_user_quest`.`catalog_id`) AS `cid`, `pxb_nce_user_quest`.`user_id` AS `uid` FROM `pxb_nce_user_quest` WHERE `pxb_nce_user_quest`.`user_id` = 335 GROUP BY `pxb_nce_user_quest`.`user_id` ORDER BY NULL
SomeModel.objects.annotate(Count('somecol'))
GROUP BY: 全部字段函數
GROUP BY: name字段,聚合somecolui
GROUP BY: 全部字段,查詢namecode
GROUP BY: name, pk字段,查詢pk字段orm
GROUP BY: name, pk字段,查詢pk字段ci
剛開始上面的查詢方法可能比較難理,可是對比原生sql語句的group by方法就會發現相似原理io
select a, b from t group by a
會正常工做,b字段會自動取第一條,等因而隱式聚合了
select a,max(b) as b from t group by
,即須要顯示的聚合全部查詢的字段
對比新版mysql語法會發現跟orm中查詢方法很相似