Я пытаюсь Django на своем бэкэнде, и в настоящее время у меня есть схема базы данных резервирования, похожая на следующую:
| Equipment id | Amount | Starting time | Ending time
| 1 | 2 | 2021-09-21 12:30 | 2021-09-21 16:00
| 1 | 3 | 2021-09-21 15:00 | 2021-09-21 20:00
| 1 | 5 | 2021-09-21 18:00 | 2021-09-21 20:00
1)
Я должен был бы рассчитать сумму максимальное количество оборудования, зарезервированное в определенном временном окне, например, 17: 00-21: 00 должно вернуть 8. Я попытался использовать queryset.annotate(maxAmount=Sum(amount))
, но в этом случае он возвращает сумму всего оборудования, зарезервированного в наборе запросов.
Может ли быть возможным решение сгруппировать резервирования с перекрывающимся временем windows, а затем узнать наибольшую сумму из этого? Какой может быть команда сгруппировать их таким образом?
2)
Вроде той же проблемы, но мне также нужно было бы найти время windows, где количество зарезервированного оборудования меньше определенного порог.
Пример с вышеприведенными данными: я бы хотел найти время, когда количество зарезервированного оборудования меньше 3: оно должно возвращать 00:00 -> 12:30, 16:00 -> 18:00 и 20 : 00 -> 00: 00.
РЕДАКТИРОВАТЬ: код, который я использую для генерации набора запросов:
def reservation_queryset(equipment_ids, starting_time, ending_time, time_between_res=0, id_to_ignore=None):
'''Queryset for returning matching reservations, for reservation checks'''
### Get reservations that are ongoing at the time with time windows at ends
# Reservations that start before this ends
timequery = Q(starting_time__lt=ending_time + timedelta(minutes=time_between_res))
# Reservations that end after this starts
timequery.add(Q(ending_time__gt=starting_time - timedelta(minutes=time_between_res)), Q.AND)
# Exclude the given reservation
equipmentquery = ~Q(id=id_to_ignore)
# Select the reservation equipments
equipmentquery.add(Q(equipments__equipment__in=equipment_ids), Q.AND)
# Combine the queries
fullquery = timequery
fullquery.add(equipmentquery, Q.AND)
# Apply the filter as distinct and get the queryset
existing_reservations = models.Reservation.objects.filter(fullquery).distinct()
return existing_reservations
РЕДАКТИРОВАТЬ # 2: И вот код, который я в настоящее время использовал, чтобы найти максимальное количество оборудования:
def get_reserved_equipments(queryset):
'''Returns a object with amounts of reserved equipments in the given queryset.'''
values = queryset.prefetch_related('equipments').values('equipments__equipment')
reserved_equipments = values.annotate(amount=Sum('equipments__amount'))
return reserved_equipments```