9

How do I get the absolute value of the annotated field? I tried the code below but it did't work.

queryset.annotate(relevance=abs(F('capacity') - int( request.GET['capacity']) ) ).order_by('relevance')

Error:

TypeError: bad operand type for abs(): 'CombinedExpression'

Thanks in advance!

Wreeecks
  • 2,186
  • 1
  • 33
  • 53

2 Answers2

15

You can try with func expressions:

from django.db.models import Func, F

queryset.annotate(relevance=Func(F('capacity') - int(request.GET['capacity']), function='ABS'))
T.Tokic
  • 1,264
  • 9
  • 10
  • @T.Tokic this doesn't work with `.annotate( distance=Func(F('datetime') - datetime_goal, function='ABS') ).order_by( 'distance' )`. It returns `ProgrammingError: function abs(interval) does not exist` – Vidak Jul 11 '18 at 15:02
  • I never used ABS with the intervals but it seems there are some workarounds for that issue: https://stackoverflow.com/questions/12004806/remove-sign-from-interval – T.Tokic Jul 11 '18 at 15:56
1

Using your own django function, you could do

from django.db.models.expressions import Func, Value

class ABS(Func):
    
    function = "ABS"

queryset.annotate(relevance=ABS(F('capacity') - Value(int(request.GET['capacity']))))
Nwawel A Iroume
  • 1,249
  • 3
  • 21
  • 42