gpt4 book ai didi

Django 过滤 timedelta 错误 : TypeError: expected string or bytes-like object

转载 作者:行者123 更新时间:2023-12-04 01:36:13 24 4
gpt4 key购买 nike

我有一个模型 Run,其中包含 start_timeend_time 时间戳,表示数据测量的开始和结束(我们称之为一个“运行”)。

class Run(models.Model):
start_time = models.DateTimeField(db_index=True)
end_time = models.DateTimeField()

最近,一位客户开始执行新类型的操作,其中一项操作要求他们知道运行的持续时间(很容易弄清楚),而且还要根据该持续时间过滤表格。

过滤是我没有的部分。因此,尝试按持续时间(我们在模型中没有的字段)进行过滤时,我提出了以下查询:

from django.db.models import F

test_query = Run.objects.all().annotate(duration=F('end_time') - F('start_time'))

通过使用 annotate 和 F 操作,我能够在我的查询中添加一个新的临时字段,称为“持续时间”。新字段的类型为 datetime.timedelta,因为它是对两个 datetime 对象执行算术运算的结果。该部分按预期工作。

问题归结为尝试通过使用 __gte__lte 查找来按新生成的注释进行过滤:

from datetime import timedelta
from django.db.models import F

test_query = Run.objects.all().annotate(duration=F('end_time') - F('start_time')).filter(duration__gte=timedelta(seconds=50))

为了简单起见,假设我只想获得 50 秒或更长的 Run,例如。

到目前为止,我对 timedelta 的工作非常简单。 end_time - start_time = timedelta_datetime_span

除了Django的filter,似乎并不想把那个作为参数传入,抛出如下错误:

Traceback (most recent call last):
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.5/contextlib.py", line 30, in inner
return func(*args, **kwds)
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/home/foo/Projects/project_foo/project_foo/comp_foo/foo/views.py", line 2790, in RunsJson
test = Run.objects.all().annotate(duration=F('end_time') - F('start_time')).filter(duration__gte=timedelta(seconds=50))
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/db/models/query.py", line 892, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/db/models/query.py", line 910, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/db/models/sql/query.py", line 1290, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/db/models/sql/query.py", line 1318, in _add_q
split_subq=split_subq, simple_col=simple_col,
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/db/models/sql/query.py", line 1207, in build_filter
condition = self.build_lookup(lookups, reffed_expression, value)
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/db/models/sql/query.py", line 1116, in build_lookup
lookup = lookup_class(lhs, rhs)
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/db/models/lookups.py", line 20, in __init__
self.rhs = self.get_prep_lookup()
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/db/models/lookups.py", line 70, in get_prep_lookup
return self.lhs.output_field.get_prep_value(self.rhs)
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/db/models/fields/__init__.py", line 1410, in get_prep_value
value = super().get_prep_value(value)
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/db/models/fields/__init__.py", line 1270, in get_prep_value
return self.to_python(value)
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/db/models/fields/__init__.py", line 1371, in to_python
parsed = parse_datetime(value)
File "/home/foo/.virtualenvs/project_foo/lib/python3.5/site-packages/django/utils/dateparse.py", line 106, in parse_datetime
match = datetime_re.match(value)
TypeError: expected string or bytes-like object

.annotate() 之后连接 .filter() 应该在新的 duration 字段上工作,因为(afaik)a __gte__lte 查找基于 datetime.timedelta 对象。

我在这里过滤有什么问题?

最佳答案

我在我的一项任务中遇到了类似您的问题。我希望这对你有用。你应该使用 ExpressionWrapper像这样的表达:

from django.db.models import ExpressionWrapper, DurationField

Run.objects.all().annotate(duration=ExpressionWrapper(F('end_time') - F('start_time'), output_field=DurationField()))

对于此解决方案,您可以使用 duration__gteduration__lte

关于Django 过滤 timedelta 错误 : TypeError: expected string or bytes-like object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59457107/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com