48👍
Use Func() expressions.
Here’s an example using the Book model from Django Aggregation topic guide to round to two decimal places in SQLite:
class Round(Func):
function = 'ROUND'
template='%(function)s(%(expressions)s, 2)'
Book.objects.all().aggregate(Round(Avg('price')))
This allows the round function to be parameterised (from @RichardZschech’s answer):
class Round(Func):
function = 'ROUND'
arity = 2
Book.objects.all().aggregate(Round(Avg('price'), 2))
👤mrts
22👍
Building on previous answers, I’ve come to this solution to make it work for PostgreSQL:
from django.db.models import Func
class Round2(Func):
function = "ROUND"
template = "%(function)s(%(expressions)s::numeric, 2)"
# Then use it as ,e.g.:
# queryset.annotate(ag_roi=Round2("roi"))
# qs.aggregate(ag_sold_pct=Round2(Sum("sold_uts") / (1.0 * Sum("total_uts"))) * 100
- [Django]-Update multiple objects at once in Django?
- [Django]-How to use custom AdminSite class?
- [Django]-Django return file over HttpResponse – file is not served correctly
16👍
Improving on @mrts answer.
This allows the round function to be parameterised:
class Round(Func):
function = 'ROUND'
arity = 2
Book.objects.all().aggregate(Round(Avg('price'), 2))
- [Django]-Celery task schedule (Ensuring a task is only executed one at a time)
- [Django]-Configuring Django to use SQLAlchemy
- [Django]-Django SUM Query?
- [Django]-Updated at field in django model
- [Django]-How to start doing TDD in a django project?
- [Django]-Django equivalent of SQL not in
5👍
I needed to have both PostgreSQL and SQLite support, but also keep the ability to specify the number of digit to keep.
Build on previous answers :
class Round(Func):
function = 'ROUND'
arity = 2
# Only works as the arity is 2
arg_joiner = '::numeric, '
def as_sqlite(self, compiler, connection, **extra_context):
return super().as_sqlite(compiler, connection, arg_joiner=", ", **extra_context)
# Then one can use it as:
# queryset.annotate(avg_val=Round(AVG("val"), 6))
I would have prefered something cleaner like
if SQLITE:
arg_joiner=", "
elif PGSQL:
arg_joiner = '::numeric, '
else raise NotImplemented()
but did not find how, feel free to improve !
- [Django]-Extending Django Admin Templates – altering change list
- [Django]-Atomic operations in Django?
- [Django]-Django: Catching Integrity Error and showing a customized message using template
Source:stackexchange.com