Как запросить перекрывающиеся даты в поле Postgres DateRange
У меня есть модель с полем PostgreSQL DateRange
:
class MyModel(models.Model):
date_range = DateRangeField()
Если я хочу сделать запрос, чтобы узнать, не накладывается ли другая дата, это достаточно просто:
MyModel.objects.filter(date_range__overlap=other_date)
Но если я построил список объектов DateRange
, как я могу искать в списке, спрашивая то же самое у списка (а не у набора запросов). Например, "Пересекается ли этот диапазон дат с любым из диапазонов дат в этом списке?":
mylist = [DateRange([2021-10-04, 2021-10-05]), DateRange([2022-10-04, 2022-10-05])]
for dr in mylist:
dr.overlap(query_date) # fails
Примечание: DateRange
объекты не имеют атрибутов overlap
согласно docs.
We know that two datetime
s do not overlap if e1≤s2 or e2≤s1 with si and ei the start and end of fragment i respectively.
This thus means that the two do overlap in case e1>s2 and e2>s1. We thus can construct an overlap check with:
def is_overlap(dr1, dr2):
return dr1.upper > dr2.lower and dr2.upper > dr1.lower
Далее мы можем выяснить, пересекается ли какой-либо из элементов с:
any(is_overlap(query_date, dr) for dr in mylist)
или мы можем построить список всех DateRange
, которые пересекаются с query_date
:
[dr for dr in mylist if is_overlap(query_date, dr)]