Почему 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},
    )
Другие вопросы по тегам