Thanks  Chris for your response; however, its not the solution I'm looking 
for. I need the ranking to go in sequential order - the solution you 
provided will just make my points, or scores in your example, the rank. I 
need, for example, the person with the highest number of scores/points with 
the rank 1 associated their record in the queryset. Then rank 2 for the 
next person with highest score/points. etc 

Any ideas on how to achieve that? Only solution I'm seeing at the moment is 
to add rank to the model and update rank every time a user calls the 
leaderboard - which would be expensive and slow wouldn't it? 

On Wednesday, June 20, 2012 8:25:06 AM UTC-7, Chris Lawlor wrote:
>
> If you can use 
> .annotate()<https://docs.djangoproject.com/en/dev/topics/db/aggregation/#generating-aggregates-for-each-item-in-a-queryset>to
>  calculate the rank, you can further filter / order the annotation 
> results.
>
> An example:
>
> class Book(models.Model):
>     title = models.CharField(max_length=120)
>     ...
>
> class Vote(models.Model):
>     user = models.ForeignKey('User')
>     score = models.IntegerField(choices=((-1, 'Thumbs Down'), (+1, 'Thumbs 
> Up')))
>     book = models.ForeignKey('Book', related_name='votes')
>
>
> To rank the Books by the sum of thumbs up and thumbs down votes, you could 
> do the following:
>
> Book.objects.all().annotate(rank=Sum('votes__score'))
>
> Each object returned by this QuerySet will now have a 'rank' attribute, 
> which is the sum of the Vote scores. You can then filter or order by rank. 
> For example, to retrieve only books with a positive overall rank:
>
>
> Book.objects.all().annotate(rank=Sum('votes__score')).filter(rank__gt=0).order_by('rank')
>
> Hope that helps.
>
> * Code isn't tested
>
> On Tuesday, 19 June 2012 13:27:21 UTC-4, Peter Ung wrote:
>>
>> Hi All,
>>
>> I'm trying to do ranking of a QuerySet efficiently (keeping it a QuerySet 
>> so I can keep the filter and order_by functions), but cannot seem to find 
>> any other way then to iterate through the QuerySet and tack on a rank. I 
>> dont want to add rank to my model. 
>>
>> I know how I can get the values I need through SQL query, but can't seem 
>> to translate that into Django:
>>
>> 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_collegebrainuserprofile 
>>>         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
>>>
>>
>> I found that if I did iterate through the QuerySet and tacked on 'rank' 
>> manually and then further filtered the results, my 'rank' would disappear. 
>> Is there any other way you can think of to add rank to my QuerySet? Is 
>> there any way I could do the above query and get a QuerySet with filter and 
>> order_by functions still intact? I'm currently using the jQuery DataTables 
>> with Django to generate a leaderboard with pagination (which is why I need 
>> to preserver filtering and order_by).
>>
>> Thanks in advance! Sorry if I did not post my question correctly - any 
>> help would be much appreciated.
>>
>> Peter
>>  
>>
>
On Wednesday, June 20, 2012 8:25:06 AM UTC-7, Chris Lawlor wrote:
>
> If you can use 
> .annotate()<https://docs.djangoproject.com/en/dev/topics/db/aggregation/#generating-aggregates-for-each-item-in-a-queryset>to
>  calculate the rank, you can further filter / order the annotation 
> results.
>
> An example:
>
> class Book(models.Model):
>     title = models.CharField(max_length=120)
>     ...
>
> class Vote(models.Model):
>     user = models.ForeignKey('User')
>     score = models.IntegerField(choices=((-1, 'Thumbs Down'), (+1, 'Thumbs 
> Up')))
>     book = models.ForeignKey('Book', related_name='votes')
>
>
> To rank the Books by the sum of thumbs up and thumbs down votes, you could 
> do the following:
>
> Book.objects.all().annotate(rank=Sum('votes__score'))
>
> Each object returned by this QuerySet will now have a 'rank' attribute, 
> which is the sum of the Vote scores. You can then filter or order by rank. 
> For example, to retrieve only books with a positive overall rank:
>
>
> Book.objects.all().annotate(rank=Sum('votes__score')).filter(rank__gt=0).order_by('rank')
>
> Hope that helps.
>
> * Code isn't tested
>
> On Tuesday, 19 June 2012 13:27:21 UTC-4, Peter Ung wrote:
>>
>> Hi All,
>>
>> I'm trying to do ranking of a QuerySet efficiently (keeping it a QuerySet 
>> so I can keep the filter and order_by functions), but cannot seem to find 
>> any other way then to iterate through the QuerySet and tack on a rank. I 
>> dont want to add rank to my model. 
>>
>> I know how I can get the values I need through SQL query, but can't seem 
>> to translate that into Django:
>>
>> 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_collegebrainuserprofile 
>>>         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
>>>
>>
>> I found that if I did iterate through the QuerySet and tacked on 'rank' 
>> manually and then further filtered the results, my 'rank' would disappear. 
>> Is there any other way you can think of to add rank to my QuerySet? Is 
>> there any way I could do the above query and get a QuerySet with filter and 
>> order_by functions still intact? I'm currently using the jQuery DataTables 
>> with Django to generate a leaderboard with pagination (which is why I need 
>> to preserver filtering and order_by).
>>
>> Thanks in advance! Sorry if I did not post my question correctly - any 
>> help would be much appreciated.
>>
>> Peter
>>  
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-users/-/zJMHkAa7ycIJ.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to