2010-04-17 3 views
6

나는 그것의 점수와 관련있는 데이타베이스에있는 목표의 계급을 찾아내는 능률적 인 방법을 찾아내는 것을 시도하고있다. 내 순진 솔루션은 다음과 같습니다order_by 후에 목록에서 결과의 위치를 ​​얻으려면 어떻게해야합니까?

rank = 0 
for q in Model.objects.all().order_by('score'): 
    if q.name == 'searching_for_this' 
    return rank 
    rank += 1 

order_by 사용하여 필터링을 수행 할 데이터베이스를 얻을 수 있어야한다 :..

Model.objects.all() order_by ('점수') 필터를 (name = 'searching_for_this')

그러나 필터 다음에 order_by 단계에 대한 색인을 검색하는 방법은없는 것처럼 보입니다.

더 좋은 방법이 있나요? (Python/django 및/또는 원시 SQL 사용)

다음 생각은 삽입시 순위를 미리 계산하는 것입니다.하지만 그것은 지저분 해 보입니다.

+0

무엇인가 : 그것은 정상적인 필드 것처럼,

from django.db.models import Count class Model(models.Model): score = models.IntegerField() ... def ranking(self): aggregate = Model.objects.filter(score__lt=self.score).aggregate(ranking=Count('score')) return aggregate['ranking'] + 1 

그런 다음 사용할 수 있습니다 어디서나 "순위"당신을 귀찮게하지 않는 경우, 나는 모델에서 사용자 정의 메소드를 만들 것 'score = = retrieve_score' -> rank – jfs

답변

7

Django ORM을 사용하여 하나의 데이터베이스 쿼리에서이 작업을 수행 할 수 있다고 생각하지 않습니다.

print Model.objects.get(pk=1).ranking 
+0

고마워, 그게 내가 원하는거야. –

+0

감사합니다. 당신이 준 예제에서, 오름차순 (즉, "낮은 점수, 높은 순위"), 그래서 나는 그것으로 갔다. 높은 점수가 실제로 순위를 높이려면 "score__lt"를 "score__gt"로 변경해야합니다. –

+2

이것은 Model.objects.all()의 각 행에 대한 순위 집계 쿼리를 실행하므로 계산 비용이 많이 든다. – mehmet

2

표준에 부합하는 데이터베이스 엔진 (PostgreSQL, SQL Server, Oracle, DB2 등)을 사용하는 "원시 SQL"에서는 SQL 표준 인 RANK 함수를 사용할 수 있습니다. 그러나 이는 널리 사용되지는 않지만 MySql과 Sqlite와 같은 비표준 엔진과 (아마도 그것 때문에) Django는이 기능을 응용 프로그램에 "적용"하지 않습니다. 이 같은

+0

아, PGSQL에 배포하기 전에 Sqlite를 테스트하고 있습니다. –

+2

@BobBob, 원한다면, 테스트 목적으로 PostgreSQL의 작은 로컬 인스턴스를 실행할 수 있습니다 - 어렵지도 번거롭지도 않습니다. –

1

사용 무언가 :

obj = Model.objects.get(name='searching_for_this') 
rank = Model.objects.filter(score__gt=obj.score).count() 

당신이 할 수있는 사전 계산 순위와 그들이 자주 사용하며 성능에 영향을 미칠 경우 모델에 저장합니다.

관련 문제