#django
Вопрос:
У меня есть модель рабочего и задачи.
У работника есть рабочее время (working_hours), а у Задачи есть время для работы (working_time).
Эти поля времени связаны с моделью timeInterval как ManyToManyField. Каждый интервал имеет время начала и окончания.
Я использовал ManyToManyField, потому что рабочий и задача могут иметь несколько интервалов в течение рабочего времени.
Например, работник может работать в промежутках с 07:00 до 12:00 и с 15:00 до 18:00. И задание должно быть выполнено с 13:00 до 17:00.
Мне нужно сделать запрос, какие задачи подходят для работника в рабочее время. Временные интервалы для работы должны перекрываться. Как я могу это сделать?
Я попытался получить интервалы рабочего времени от конкретного работника, а затем в цикле сформировать условие для фильтрации с использованием Q-объектов. Подобный этому:
my_worker = Worker.objects.get(id=1)
my_worker_working_hours = my_worker.working_hours.all()
time_conditions = []
for interval in my_worker_working_hours:
time_conditions.append(
Q(
Q(working_time__start__lte=interval.end) amp;
Q(working_time__end__gte=interval.start)
)
)
suitable_task = Task.objects.filter(*time_conditions)
Это работает, если задача имеет только один интервал рабочего времени. В противном случае фильтр работает неправильно.
Мои модели:
class Worker(models.Model):
name = models.CharField(max_length=10)
working_hours = models.ManyToManyField(TimeInterval)
class Task(models.Model):
name = models.CharField(max_length=10)
is_assigned = models.BooleanField(default=False)
working_time = models.ManyToManyField(TimeInterval)
class TimeInterval(models.Model):
start = models.TimeField()
end = models.TimeField()
Обновить
Я использую SQLite. Я обнаружил, что в Django есть поле DateTimeRangeField для PostgreSQL. Решает ли это мою проблему? Я не очень хорошо знаком с PostgreSQL.
Комментарии:
1. Вы хотите найти задачи, которые лежат в интервале 1 ИЛИ интервале 2 ИЛИ…, да?
2. @AbdulAzizBarkat , Да, хотя бы один временной интервал должен перекрываться
Ответ №1:
Вы используете оператор или (канал) с Q объектами.
suitable_tasks = Task.objects.none()
for interval in my_worker_working_hours:
suitable_tasks |= Task.objects.filter(
Q(working_time__start__lte=interval.end) amp;
Q(working_time__end__gte=interval.start))