Bahman Rouhani
Bahman Rouhani

Reputation: 1259

Django sort records by calculated field

I have a model:

class Person(models.Model):
    score1 = models.FloatField(default=0)
    score2 = models.FloatField(default=0)
    score3 = models.FloatField(default=0)

and I need to sort the records by the average score (i.e. (score1 + score2 + score3)/3) in descending order.

For the following list of Persons:

p1 = Person(score1=3, score2=4, score3=5) # avg = 4
p2 = Person(score1=3, score2=2, score3=1) # avg = 2

the result should be:

[<p2>, <p1>]

Upvotes: 1

Views: 1582

Answers (1)

user3850
user3850

Reputation:

You can use F-expressions to annotate each row with the average score:

from django.db.models import F

ps_with_avg = Person.objects.annotate(
    avg=(F('score1')+F('score2')+F('score3'))/3
)

and then order them by the avg score like so:

ordered_ps = ps_with_avg.order_by('-avg')

Check the generated SQL to verify it does what you want:

print(ordered_ps.query)

Upvotes: 4

Related Questions