Skip to content

Instantly share code, notes, and snippets.

@iandmyhand
Last active January 8, 2023 08:10
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save iandmyhand/b2c32311715113e8c470932a053a6732 to your computer and use it in GitHub Desktop.
Save iandmyhand/b2c32311715113e8c470932a053a6732 to your computer and use it in GitHub Desktop.
Django ORM function to sum absolute values.
from django.db.models import Sum
class AbsoluteSum(Sum):
name = 'AbsoluteSum'
template = '%(function)s(%(absolute)s(%(expressions)s))'
def __init__(self, expression, **extra):
super(AbsoluteSum, self).__init__(
expression, absolute='ABS ', output_field=IntegerField(), **extra)
def __repr__(self):
return "SUM(ABS(%s))".format(
self.arg_joiner.join(str(arg) for arg in self.source_expressions)
)
@iandmyhand
Copy link
Author

'test' table

name amount
A 3
B 1
C -2

'Test' model

class Test(Model):
  name=CharField(max_length=1)
  amount=IntegerField()

Usage

result = Test.objects.annotate(
  absolute_sum=AbsoluteSum('amount'),
  normal_sum=Sum('amount')
).values(
  'absolute_sum',
  'normal_sum'
)
print(str(result.query))  # SELECT (SUM(ABS(`test`.`amount`))) AS `absolute_sum`, (SUM(`test`.`amount`)) AS `normal_sum` FROM `test`

Result

print(result['absolute_sum'])  # 6
print(result['normal_sum'])  # 2

@liansheng
Copy link

very good

@LowerDeez
Copy link

Nice

@skyl
Copy link

skyl commented Jan 8, 2023

still works ;d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment