Почему django-q выдает исключение со стрелкой времени
Я пытаюсь создать расписание Django-q и следую документам, чтобы использовать
arrow
при следующем запуске получаю следующую ошибку с расписанием:
schedule(
func='test.tasks.test_task',
name='test_task_nightly',
schedule_type=Schedule.DAILY,
next_run=arrow.utcnow().replace(hour=23, minute=30),
q_options={'timeout': 10800, 'max_attempts': 1},
)
Traceback (most recent call last):
File "/usr/lib/python3.8/code.py", line 90, in runcode
exec(code, self.locals)
File "<console>", line 1, in <module>
schedule(
File "/home/user/PycharmProjects/app/venv/lib/python3.8/site-packages/django_q/tasks.py", line 122, in schedule
s.full_clean()
File "/home/user/PycharmProjects/app/venv/lib/python3.8/site-packages/django/db/models/base.py", line 1209, in full_clean
self.clean_fields(exclude=exclude)
File "/home/user/PycharmProjects/app/venv/lib/python3.8/site-packages/django/db/models/base.py", line 1251, in clean_fields
setattr(self, f.attname, f.clean(raw_value, self))
File "/home/user/PycharmProjects/app/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py", line 650, in clean
value = self.to_python(value)
File "/home/user/PycharmProjects/app/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py", line 1318, in to_python
parsed = parse_datetime(value)
File "/home/user/PycharmProjects/app/venv/lib/python3.8/site-packages/django/utils/dateparse.py", line 107, in parse_datetime
match = datetime_re.match(value)
TypeError: expected string or bytes-like object
Не уверен, почему он не принимает формат времени, аналогичный примеру, приведенному на странице документации django-q.
РЕДАКТИРОВАТЬ: запланированная задача:
def test_task():
print('Executed test task')
Ничего слишком сложного только для тестирования
1 ответ
Django ORM (версия 3.2 на момент написания) не принимает объект Arrow ни в каком
DateTimeField
.
Объекты-стрелки имитируют объектный интерфейс Python, но они не являются настоящими объектами. Таким образом, любой код, получающий объект Arrow, потерпит неудачу, если он явно проверяет, является ли ваше значение добросовестным. Это именно то, что код в
django.db.models.fields.DateTimeField.to_python
кажется, делает:
def to_python(self, value):
if value is None:
return value
if isinstance(value, datetime.datetime):
return value
if isinstance(value, datetime.date):
value = datetime.datetime(value.year, value.month, value.day)
...
try:
parsed = parse_datetime(value)
Как видите, когда он не соответствует или
date
например, Django передает его
parse_datetime()
функция для обработки, которая ожидает строку. Это объясняет вашу ошибку:
TypeError: expected string or bytes-like object
Вы можете обойти это, получив
.datetime
свойство, которое вернет простой старый питон
datetime
, т.е.
schedule(
func='test.tasks.test_task',
name='test_task_nightly',
schedule_type=Schedule.DAILY,
next_run=arrow.utcnow().replace(hour=23, minute=30).datetime,
q_options={'timeout': 10800, 'max_attempts': 1},
)