Как выполнить аналитику по нескольким подсчетам с помощью django?

У меня есть аналитическая панель - в основном она показывает обзор данных. Допустим, у нас есть таблица с именем "Records"

В моей панели аналитики мне нужно показать различные подробности о записях конкретного пользователя:

user = Records.objects.filter(id=pk)

В результате мы получаем все записи, связанные с пользователем, теперь нужно показать различные аналитические данные, как показано ниже,

Total Records,
Total Records by Today
Total Records by Week
Total Records by Month
Total Active Records // Records which has status == active
Total InActive Records // Records which has status == inactive

Как все это сделать? В ходе исследования я нашел несколько вариантов, которым можно следовать,

Вариант 1: Выполнить отдельный запрос для каждой потребности
. Вариант 2: Выполнить выборку всех данных и выполнить вышеуказанные вычисления в представлении и отправить как контекст

Как с этим быть? Я также планирую использовать графики

Class Records:
    owner = models.ForeignKey(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=120)
    code = models.CharField(max_length=16)
    type = models.CharField(max_length=32)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now = True)

Если вы планируете использовать библиотеку фронтенда, такую как Chart.js (которую я настоятельно рекомендую), у вас есть два подхода:

  1. Создайте структуру данных для каждого запроса на бэкенде и передайте все данные сразу на фронт-энд

    .
    • Преимущества:
      • После того, как данные доступны во фронт-энде, скрипты рендеринга будут выполняться намного быстрее (например, изменение графиков)
    • Недостатки
      • Инициализация данных может занять больше времени, так как бэкэнд делает много дел одновременно
      • .
      • Код бэкенда может стать избыточным или чрезмерно сложным и трудно управляемым
  2. Создайте конечную точку на бэкенде и динамически запрашивайте ее с фронтэнда

    .
    • Преимущества:
      • Бэкэнд выполняет меньше работы для каждого отдельного запроса, поэтому загрузка происходит быстрее
    • Недостатки:
      • Пользователи, которые постоянно перелистывают графики, могут испытывать задержку при ожидании выполнения каждого запроса
      • .

Очевидно, что это не исчерпывающий список плюсов и минусов каждого варианта, хотя обычно я выбираю вариант 2 в своих проектах.

В идеале Делайте работу с базой данных в базе данных, а не в Python, если только у вас нет бюджетных ограничений на использование службы базы данных (хотя в этом случае работа будет переложена на ваш app worker). Поскольку вас интересует только количество элементов, вы можете просто использовать QuerySet.count(). См. раздел Field Lookups для справки о запросах, сделанных ниже.

from datetime import datetime, date

user_records = Records.objects.filter(owner=some_user)
today = date.today()

total_records = user_records.count()
total_records_today = user_records.filter(created_at__date=today).count()
total_records_week = user_records.filter(created_at__year=today.year, created_at__week=today.isocalendar()[1]).count()
total_records_month = user_records.filter(created_at__year=today.year, created_at__month=today.month).count()
total_records_active = user_records.filter(status="active").count()
total_records_inactive = user_records.filter(status="inactive").count()

Или вы также можете вручную выполнить подсчет по всем записям:

for rec in user_records:
    if rec.created_at.date() == today:
        total_records_today += 1
    if rec.created_at.date().isocalendar()[1] == today.isocalendar()[1]:
        total_records_week += 1
    ...

Ор:

total_records_today = len(list(filter(lambda rec: rec.created_at.date() == today, user_records)))
total_records_week = len(list(filter(lambda rec: rec.created_at.date().isocalendar()[1] == today.isocalendar()[1], user_records)))
...
Вернуться на верх