2012-12-03 56 views
1

想象我只是想知道用戶的數量與Django的權威性應用相同FIRST_NAME。 我知道如何做到這一點很容易在SQL:Django的真正簡單的聚合(或一組)

SELECT first_name, COUNT(1) as num_users 
    FROM auth_user 
    GROUP BY first_name 
    ORDER BY num_users DESC; 

而且我也知道如何獲得所需的輸出在Django(如想通過所有的用戶去,得到他們的電子郵件,做一個過濾和例如count)。

是不是有一個簡單的方法來通過Django的ORM做到這一點?我可以完成它,如果我聚合與外鍵但不與表字段之一。我很確定我錯過了一些東西。

謝謝。

回答

1

我幾年前在博客this very issue 。與其他答案相反,在Django中完全可能,不需要原始SQL。

+0

從來不知道這一點。很有用。 –

+0

謝謝@ daniel-roseman :)就像你在博客中說的那樣,它有很好的文檔記錄,我讀過很多次,但沒有得到它:/並且我認爲你說得對,因爲(可能是正確的)不希望用SQL來表達事情的願望,要找到「 – Tiago

0

檢查:https://docs.djangoproject.com/en/dev/topics/db/aggregation/

from django.db.models import Count 
auth_user.objects.annotate(num_users=Count('first_name')) 

對於更復雜的查詢,你可以使用普通的SQL,但儘量避免它。

UPD固定的代碼。感謝蒂米奧馬霍尼提及!

+0

這隻會計數並返回所有擁有first_name集合的用戶。 –

1

Django的annotations允許您爲查詢集中的每個對象(或整個查詢集中的聚合)附加一些基本計算,但無法過濾這些註釋(即,對於您的情況,您只需要計算那些共享您的用戶名稱)

Django也有F() objects它允許您在查詢中使用字段值。理想情況下,你可以結合使用這些帶有註釋的過濾你的註釋對象,but that's not currently possible (there's a fix on the way)

所以,一個簡單的辦法是進行手動註釋:

users = User.objects.all().extra(select={ 
    'same_name_count' : """ 
    SELECT COUNT(*) 
    FROM auth_user 
    WHERE auth_user.first_name = user.first_name 
    """ 
})