Во-первых, укажите свой возраст для набора запросов с помощью:
age = ExpressionWrapper(datetime.now() - F('created_at'), output_field=fields.DurationField())
queryset.annotate(age=age) #=> Will add "age" on each records
Во-вторых, используйте Case / When, чтобы создать собственную логику в поле age_range
queryset.annotate(age=age).annotate(
age_range=Case(
When(age__gte=datetime.timedelta(years=10), age__lt=datetime.timedelta(years=20), then=Value('teens')),
When(age__gte=datetime.timedelta(years=20), age__lt=datetime.timedelta(years=30), then=Value('twenties')),
When(age__gte=datetime.timedelta(years=30), age__lt=datetime.timedelta(years=40), then=Value('thirties')),
When(age__gte=datetime.timedelta(years=40), age__lt=datetime.timedelta(years=50), then=Value('fourties')),
When(age__gte=datetime.timedelta(years=50), then=Value('fifties')),
default=Value('Unknow'),
output_field=fields.CharField(),
)) #=> This will add "age_range" field on your queryset
Третье, просто агрегировать по "age_range".Все вместе:
import datetime
from django.db.models import Case, When, Value, F, Count, ExpressionWrapper, fields
age = ExpressionWrapper(datetime.now() - F('created_at'), output_field=fields.DurationField())
counts = queryset.annotate(age=age).annotate(
age_range=Case(
When(age__gte=datetime.timedelta(years=10), age__lt=datetime.timedelta(years=20), then=Value('teens')),
When(age__gte=datetime.timedelta(years=20), age__lt=datetime.timedelta(years=30), then=Value('twenties')),
When(age__gte=datetime.timedelta(years=30), age__lt=datetime.timedelta(years=40), then=Value('thirties')),
When(age__gte=datetime.timedelta(years=40), age__lt=datetime.timedelta(years=50), then=Value('fourties')),
When(age__gte=datetime.timedelta(years=50), then=Value('fifties')),
default=Value('Unknow'),
output_field=fields.CharField(),
)).order_by('age_range').values('age_range').annotate(count=Count('age_range'))