1. Рабочие часы - это тип данных str а не datetime! Почему? Потому, что Datetime в любом случае возвращает конкретную дату. Как надо себе это представлять:
start_time: str = '12:20'
end_time: str = '16:00'
Есть ещё TimeField, но тогда надо будет в поле объявлять format=
2. Есть несколько вариантов записи этих данных в модель. Самый простой - через Choices:
class WorkDay(models.Model):
DAYS_OF_WEEK = (
(1, _('Monday')),
(2, _('Tuesday')),
(3, _('Wednesday')),
(4, _('Thursday')),
(5, _('Friday')),
(6, _('Saturday')),
(7, _('Sunday')),
)
DAY_TYPES = (
('weekday', _('weekday')),
('holiday', _('holiday')),
)
day_of_the_week = models.PositiveIntegerField(
verbose_name=_('day of the week'),
choices=DAYS_OF_WEEK
)
start_time = models.CharField(
verbose_name=_('start time'),
max_length=5
)
end_time = models.CharField(
verbose_name=_('end time'),
max_length=5
)
day_type = models.CharField(
verbose_name=_('day type'),
max_length=255,
choices=DAY_TYPES
)
3. Нам может потребоваться записать в рабочий день несколько пар рабочих часов. В этом случае, наиболее верным способом я счёл бы использование
ArrayField или
ListFieldfrom django.contrib.postgres.fields import ArrayField
class WorkDay(models.Model):
DAYS_OF_WEEK = (
(1, _('Monday')),
(2, _('Tuesday')),
(3, _('Wednesday')),
(4, _('Thursday')),
(5, _('Friday')),
(6, _('Saturday')),
(7, _('Sunday')),
)
DAY_TYPES = (
('weekday', _('weekday')),
('holiday', _('holiday')),
)
day_of_the_week = models.PositiveIntegerField(
verbose_name=_('day of the week'),
choices=DAYS_OF_WEEK
)
working_hours = ArrayField(
ArrayField(
models.CharField(
max_length=5
),
size=2
),
verbose_name=_('working hours')
)
day_type = models.CharField(
verbose_name=_('day type'),
max_length=255,
choices=DAY_TYPES
)
4. Также, мы можем использовать JSONField (
MySQL или
PostgreSQL )
from django.contrib.postgres.fields import JSONField
class WorkGraph(models.Model):
working_graph = JSONField(
verbose_name=_('working graph'),
default={
'monday': {
'hours': ['12:20', '16:00'],
'day_type': 'weekday'
}
}
)
Я бы предпочёл вариант с ArrayField.
ArrayField как и JSONField поддерживаются DRF и представляют данные в виде массивов Python, которые можно отработать через validate.
При таком подходе фронт берёт на себя построение UI, при котором пользователь просто выбирает часы и минуты в форме и добавляет их. JS строит на основе формы массив и передаёт в DRF.
И бонусом, используем валидацию для полей
Django и
DRF:
import re
from django.core.exceptions import ValidationError
from typing import NoReturn
def validate_working_hours(
value: str
) -> NoReturn:
m = re.match(
r'^(?P<hours>\d{2}):(?P<minutes>\d{2})$',
value
)
if m is None:
raise ValidationError('please, use format HH:mm')
else:
hours = int(
m.group('hours')
)
if hours > 23:
raise ValidationError('hours is a value from 0 to 23')
minutes = int(
m.group('minutes')
)
if minutes > 59:
raise ValidationError('minutes is a value from 0 to 59')