fetching row numbers in a database-independent way - django
-
13-09-2019 - |
Question
Let's say that I have a 'Scores' table with fields 'User','ScoreA', 'ScoreB', 'ScoreC'. In a leaderboard view I fetch and order a queryset by any one of these score fields that the visitor selects. The template paginates the queryset. The table is updated by a job on regular periods (a django command triggered by cron).
I want to add a 'rank' field to the queryset so that I will have 'rank', 'User', 'ScoreA', 'ScoreB', 'ScoreC'. Moreover I want to remain database-independent (postgre is an option and for the time being it does not support row_number).
A solution may be that I can modify the job, so that it also computes and writes three different ranks in three new fields ('rankA', 'rankB', 'rankC').
I hope there is a (much) better solution?
Solution
Why can't you compute the rank in the template?
{% for row in results_to_display %}
<tr><td>{{forloop.counter}}</td><td>{{row.scorea}}</td>...
{% endfor %}
Or, you can compute the rank in the view function.
def fetch_ranked_scores( request ):
query = Score.objects.filter( ... ).orderby( scorea )
scores = [ r, s.scorea for r, s in enumerate(query) ]
return render_to_response ( template, { 'results_to_display':scores } )
Or, you can compute the ranking in the model.
class Score( models.Model ):
ScoreA = models.IntegerField( ... )
def ranked_by_a( self ):
return enumerate( self.objects.filter(...).orderby( scorea ) )
I think there are many, many ways to do this.