It isn’t possible to order by the result of the
calculated_totalmethod.
However, you can set the default ordering for your model admin by overriding
the
get_queryset
method for your model admin, and ordering by an
expression that calculates the same thing.
class OrderModelAdmin(admin.ModelAdmin): ... def get_queryset(self, request): qs = super(OrderModelAdmin, self).get_queryset(request) qs = qs.order_by(F('cost')*F('quantity')) return qsA similar approach is to annotate the queryset with the total, and then order
by that field. Assuming that cost is a
DecimalFieldand quantity is an
IntegerField, you need to use
expressionWrapperto set the output field.
See the docs on Using F() with
annotations for more info.
I don’t think it’s possible to use
totaldirectly in
list_display.
However, you can alter your
calculated_totalmethod to access the annotated
field. We set
calculated_total.admin_order_field = 'total'so that the
Django admin allows you to sort on that column by clicking on it.
from django.db.models import F, expressionWrapper, DecimalFieldclass OrderModelAdmin(admin.ModelAdmin): list_display = ['name', 'number', 'price', 'calculated_total'] def calculated_total(self, obj): return obj.total calculated_total.admin_order_field = 'total' def get_queryset(self, request): qs = super(OrderModelAdmin, self).get_queryset(request) qs = qs.annotate(total=expressionWrapper(F('cost')*F('quantity'), output_field=DecimalField())).order_by('total') return qs


