2012-06-21 7 views
2

나는 (필터와 order_by 함수를 유지할 수 있도록 QuerySet을 유지하면서) QuerySet의 순위를 효율적으로 만들려고 시도하고 있지만 QuerySet을 통해 반복하고 순위를 정하는 다른 방법을 찾지 못하는 것처럼 보입니다. 나는 내 모델에 순위를 추가하고 싶지 않아도된다.QuerySet에서 순위를 매기는 가장 효율적인 방법은 무엇입니까?

나는 내가 SQL 쿼리를 통해 필요한 값을 얻을 수있는 방법을 알고 있지만, 장고에 그 번역 수없는 것 :

SET @rank = 0, @prev_val = NULL; 
SELECT rank, name, school, points FROM 
    (SELECT @rank := IF(@prev_val = points, @rank, @rank+1) AS rank, @prev_val := points, points, CONCAT(users.first_name, ' ', users.last_name) as name, school.name as school 
    FROM accounts_userprofile 
     JOIN schools_school school ON school_id = school.id 
     JOIN auth_user users ON user_id = users.id 
    ORDER BY points DESC) as profile 
ORDER BY rank DESC 

나는 내가 검색어 세트를 반복했고, 경우 '에 압정으로 고정 발견 순위 '를 수동으로 설정하고 결과를 추가로 필터링하면 내'순위 '가 사라지게됩니다. 목록으로 변환하지 않으면 필터링 및 정렬이 약간 어려워집니다. QuerySet에 순위를 추가하는 다른 방법이 있습니까? 위의 쿼리를 수행하고 filter 및 order_by 함수가있는 QuerySet을 그대로 유지할 수있는 방법이 있습니까? 현재 장고와 함께 jQuery DataTables를 사용하여 페이지 매김을 사용하여 리더 보드를 생성하고 있습니다 (이것이 내가 preserver 필터링 및 order_by를 필요로하는 이유입니다).

미리 감사드립니다. 미안, 내 질문을 올바르게 게시하지 않았다면 어떤 도움을 주시면 감사하겠습니다.

답변

0

본인은 직접 사용하지 않았지만 extra() 방법으로 해결할 수 있습니다.

0

원시 SQL을 보면 논리에 특별한 것이 보이지 않습니다. 동일한 포인트 값을 동일한 순위로 축소하는 동안 카운터에서 1로 정렬 된 조인 순서로 모든 SQL 행을 열거하고 있습니다.

내 제안은 raw() 또는 extra() 메소드를 사용하는 사용자 정의 관리자를 작성하는 것입니다. 관리자는 모든 모델 인스턴스에 python의 열거 형을 이전에 points으로 정렬 된 순위로 사용합니다. 물론 현재 최대 점 값을 유지해야하며 같은 양의 점을 가진 경우 열거 형이 반환하는 값을 무시해야합니다. 유사한 예를 보려면 here을보십시오.

그럼 당신은 같은 것을 할 수있는 : 나는) (추가를 사용하여 시도했다

YourQuerySet.objects.with_rankings().all() 
+0

, 그러나 그것의 순위를 계산하기 이전 행에 대한 종속성이 있습니다. 나는 그것이 작동하도록 할 수 없습니다. – Petethesweets

+0

SQL 커서를 사용하여 작성한 SQL을 수행 할 수는 있지만 반드시 수행해야 할 이유는 없습니다. 랭크 카운트를 파이썬으로 연기하여 단순히 열거하고 이전 행 랭크를 기반으로 마지막 랭크를 추적 할 수 있습니다. 이 평가를 SQL 수준으로 밀어 넣으려는 노력은 최소한의 오버 헤드 일 수 있습니다. – astevanovic

+0

내가 무슨 뜻인지 알 것 같지만 내 경우에는 약간 비효율적 인 것처럼 보입니다. 저는 수천 장의 기록을 가지고 있습니다. 그리고 queryset을 거쳐 순위를 매기려고 시도했습니다 - record.rank = 뭐든간에. 그러나 반환 된 쿼리 세트를 필터링하면 순위 계산이 제거됩니다. 내 모델에 순위를 추가하는 것만이 효율적인 방법 일 수 있습니까? – Petethesweets

관련 문제