Auto increment rank field in my response in Django Rest Framework

Question:

I’ve a StudentAnswer model which stores the answer id given by the student(User) in a quiz. If the answer is correct then 1 marks else 0. The model looks like this:

class StudentAnswer(models.Model):
    user = models.ForeignKey(User, related_name='user_question_answer', 
                on_delete=models.SET_NULL,null=True, blank=True)
    answer = models.ForeignKey(QuizQuestionAnswer, related_name='user_answer', 
                on_delete=models.CASCADE)
    quiz = models.ForeingKey(Quiz, on_delete=models.CASCADE)
    marks = models.IntegerField()

Now I need my response to look something like this:
{
"rank": 1,
"user": "John Doe",
"marks": 10
},
{
"rank": 2,
"user": "Stanley",
"marks": 8
}

I don’t have a rank field in my model. I want rank in my response and that too according to the marks of students(highest to lowest). How can I do it?

Asked By: Arthur Dayne

||

Answers:

The absolutely easiest way to do this is to use order_by('marks') and then in your view or template, when you are looping through each User, their rank is just the index of the loop. Two examples:

# template
{% for student in students %}
    # rank is {{ forloop0.counter }}
{% endfor %}
# views
for index, value in enumerate(students):
    # rank is index
    ...

If you want to explicitly add the rank to the queryset then you can use annotation, see the answer to this question: Django model – how to add order index annotation?

from django.db.models import Window, F
from django.db.models.functions import DenseRank

ranklist = Score.objects.annotate(
    place=Window(
        expression=DenseRank(),
        order_by=[
            F('points').desc(),
        ])) 
Answered By: 0sVoid