django - ordering queryset by a calculated field

Solution 1:

If you would not mind some logic duplicaton, then the following will work:

Foo.objects.extra(select={'d_field': 'A - B'}).extra(order_by=['d_field'])

Solution 2:

Please refrain from using extra() as it's meant to be deprecated in the future.

Since Django 1.7 you can use a combination of annotate() and order_by() to achieve this

Foo.objects.annotate(ordering=F('A') - F('B')).order_by('ordering')

There's also ungoing work to allow expressions to be used all over the ORM so the following should work in future versions of Django:

Foo.objects.order_by(F('A') - F('B'))