Количество запросов к базе данных в Views с использованием Django
Мой вопрос касается лучших практик для запроса базы данных в представлении с помощью Django.
Мне нужен ежедневный подсчет бронирований за последние 7 дней. Можно ли иметь что-то подобное? (ниже)
count_day_1 = len(Reservations.objects.filter(date=TODAY_DATE).filter(is_reserved=True))
count_day_2 = len(Reservations.objects.filter(date=DATE_TODAY_MINUS_1).filter(is_reserved=True))
count_day_3 = len(Reservations.objects.filter(date=DATE_TODAY_MINUS_2).filter(is_reserved=True))
count_day_4 = len(Reservations.objects.filter(date=DATE_TODAY_MINUS_3).filter(is_reserved=True))
count_day_5 = len(Reservations.objects.filter(date=DATE_TODAY_MINUS_4).filter(is_reserved=True))
count_day_6 = len(Reservations.objects.filter(date=DATE_TODAY_MINUS_5).filter(is_reserved=True))
count_day_7 = len(Reservations.objects.filter(date=DATE_TODAY_MINUS_6).filter(is_reserved=True))
Или наличие этого Reservations.objects.filter() в нем 7 раз пингует базу данных 7 раз?
Если вышеупомянутый способ не рекомендуется, должен ли я настроить его следующим образом? (ниже)
data = Reservations.objects.filter(is_reserved=True)
for item in data:
if item.date == TODAY_DATE:
print(item.date)
if item.date == DATE_TODAY_MINUS_1:
print(item.date)
(...so on and so forth)
Любой совет будет замечательным.
Спасибо!
сначала мы получим объект datetime даты 7 дней назад
from datetime import datetime, timedelta
previous_date = datetime.now() - timedelta(days=7)
Затем мы воспользуемся TruncDate
и получим подсчеты по дате
from django.db.models.functions import TruncDate
from django.db.models import Count
data = Reservations.objects.filter(date__gte=previous_date, is_reserved=True)\
.annotate(day=TruncDate('date'))\
.values('day').annotate(count=Count('id'))\
.values('day', 'count')
Это даст вам результат примерно такой
<QuerySet [{'day': datetime.date(2021, 8, 10), 'count': 5},
{'day': datetime.date(2021, 8, 11), 'count': 4},
{'day': datetime.date(2021, 8, 12), 'count': 4},
{'day': datetime.date(2021, 8, 13), 'count': 6}]>
Идея взята из этого ответа пожалуйста, смотрите больше в официальной документации о annotate, TruncDate, TruncMonth, TruncYear