Django Aggregates Over JSONB
I wanted to park this here because it’s useful. You can do aggregates over nested JSONB fields in Django via a series of casts, which you can express using only the ORM. Heres a simple examples. This is based on a real-world example where I had to cast the float to an integer, which is a bonus little easter egg.
from django.db.models import Sum, IntegerField, FloatField, TextField
from django.db.models.functions import Cast
from django.utils import timezone
from datetime import timedelta
class TicketReport:
= models.DatetimeField()
timestamp = JSONField()
tickets
def get_ticket_count_30_day(self):
= obj.report_set\
qs filter(timestamp__gt=timezone.now() - timedelta(days=30))\
.=Cast(Cast(Cast('tickets', TextField()), FloatField()), IntegerField()))\
.annotate(numeric_val'numeric_val'))
.aggregate(Sum(= qs['numeric_val__sum'] or 0
ds return ds
Assume the JSON looks something like this, and you take part of that
value and extract it into the tickets
field:
{
"tickets": 2516.0
}
You can directly cast the value into an Integer and then aggregate over it.