为啥django-q会用箭头时间抛出异常
Posted
技术标签:
【中文标题】为啥django-q会用箭头时间抛出异常【英文标题】:Why does django-q throw exception with arrow time为什么django-q会用箭头时间抛出异常 【发布时间】:2021-07-29 13:50:18 【问题描述】:我正在尝试创建一个 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 版)不接受任何 DateTimeField
中的 Arrow 对象。
Arrow 对象模拟 Python 的 datetime
对象接口,但它们不是真正的 datetime
对象。因此,如果接收到 Arrow 对象的任何代码都明确检查您的值是否是诚实的 datetime
,它将失败。这正是代码中的内容
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)
如您所见,当它与datetime
或date
实例不匹配时,Django 将其交给parse_datetime()
函数处理,该函数需要一个字符串。这解释了你的错误:TypeError: expected string or bytes-like object
您可以通过获取.datetime
属性来解决此问题,该属性将返回一个普通的旧python 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,
)
【讨论】:
以上是关于为啥django-q会用箭头时间抛出异常的主要内容,如果未能解决你的问题,请参考以下文章