Фильтр и группировка по возрасту пользователя - Django

Я создаю таблицу диаграмм, которую я хотел бы сгруппировать и подсчитать по целочисленным диапазонам (возрастам) пользователей в этом объекте.

Таблица для примера:

Name   Age
John   21
Steve  24
Dan    29 
Mike   31 

и мой ожидаемый результат:

[20-25] [26-31]
   2       2

Я играл с функцией annotate в Django, но пока не смог разобраться. Есть предложения по этому поводу?

Мой views.py:

qs = Post.objects.filter(spot=spot).annotate(
     age_group = Case(
          When(attendant__profile__age__range=[21, 27], then=Value('21-27')).count(),
          When(attendant__profile__age__range=[29, 33], then=Value('29-33')).count(),
          default=Value('No group'),
          output_field=CharField(),
             )
        ).values('age', 'age_group')

models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    birthday = models.DateField(null=True, blank=False)

    def age(self):
        return int((datetime.date.today() - self.birthday).days / 365.25)

Вы можете использовать Conditional Aggregation для подсчета только тех строк, которые соответствуют определенному критерию. Вы не можете фильтровать по значению, предоставленному методом экземпляра, но вы должны выполнить вычисление внутри базы данных, используя ORM Django.

Смотрите пример ниже для аннотации одной возрастной группы, вероятно, вычислить возраст точно немного сложнее (посмотрите в Django's Field Lookups, если вы, например, хотите использовать только date), но вы должны понять идею.

from datetime import datetime, timedelta
from django.db.models import Count, Q

now = datetime.now()
year = timedelta(days=1) * 365

qs = Post.objects.filter(spot=spot).annotate(
    age_group_1=Count("pk", 
        filter=Q(attendant__profile__birthday__range=[now - (27 * year), now - (21 * year)])
    )
)
Вернуться на верх