Python Django&;SQLite:DurationField算法
我有下面的型号Python Django&;SQLite:DurationField算法,python,django,sqlite,duration,timedelta,Python,Django,Sqlite,Duration,Timedelta,我有下面的型号 class MyModel(models.Model): start = models.TimeField() finish = models.TimeField() penalty = models.IntegerField(blank=True, default=0) # penalty in minutes 以及以下管理中的queryset注释 def get_queryset(self, request): qs = super().g
class MyModel(models.Model):
start = models.TimeField()
finish = models.TimeField()
penalty = models.IntegerField(blank=True, default=0) # penalty in minutes
以及以下管理中的queryset注释
def get_queryset(self, request):
qs = super().get_queryset(request)
qs = qs.annotate(
total_time=ExpressionWrapper(
F("finish") - F("start") + F("penalty") * 60,
output_field=DurationField()
)
)
return qs
当我检查惩罚!=0
我得到类似于datetime.timedelta(018001800)
(在这种情况下,惩罚是30分钟)。
但是,我希望使用类似于
datetime.timedelta(03600)
的timedelta。有人能解释一下吗
我也试过了
def get_queryset(self, request):
qs = super().get_queryset(request)
qs = qs.annotate(
duration=ExpressionWrapper(
F("finish") - F("start"),
output_field=DurationField()
)
)
qs = qs.annotate(
total_time=ExpressionWrapper(
F("duration") + F("route_shortening_penalty") * 60,
output_field=DurationField()
)
)
return qs
甚至
def get_queryset(self, request):
qs = super().get_queryset(request)
qs = qs.annotate(
duration=ExpressionWrapper(
F("finish") - F("start"),
output_field=DurationField()
),
penalty_duration=ExpressionWrapper(
F("penalty") * 60,
output_field=DurationField()
)
)
qs = qs.annotate(
total_time=ExpressionWrapper(
F("duration") + F("penalty_duration"),
output_field=DurationField()
)
)
return qs
这两种情况都会导致
Traceback (most recent call last):
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/core/handlers/base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/contrib/admin/options.py", line 604, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/utils/decorators.py", line 142, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/contrib/admin/sites.py", line 223, in inner
return view(request, *args, **kwargs)
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/utils/decorators.py", line 45, in _wrapper
return bound_method(*args, **kwargs)
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/utils/decorators.py", line 142, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1793, in changelist_view
'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)},
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/db/models/query.py", line 250, in __len__
self._fetch_all()
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/db/models/query.py", line 1186, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/db/models/query.py", line 63, in __iter__
for row in compiler.results_iter(results):
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1009, in apply_converters
value = converter(value, expression, connection)
File "/home/dm/.virtualenvs/test/lib/python3.6/site-packages/django/db/backends/base/operations.py", line 573, in convert_durationfield_value
return datetime.timedelta(0, 0, value)
TypeError: unsupported type for timedelta microseconds component: str
我正在使用
python3.6.7
,Django==2.1.7
和SQLite版本3022000
,如果你得到的是datetime.timedelta(0,1800,1800)
而不是正确的datetime.timedelta(0,3600)
,那么你显然就快到了
我假设1800秒是F(“完成”)
和F(“开始”)
之间的差,而1800微秒来自F(“惩罚”)*60
用60*1000*1000
而不是60
相乘,将惩罚
从分钟转换为微秒:
total_time=ExpressionWrapper(
F("finish") - F("start") + F("penalty") * 60000000,
output_field=DurationField()
)
如果惩罚是一个
DurationField
而不是一个IntegerField
,这不是更有意义吗?@JohnGordon也尝试过了,请参见更新的问题。为什么不使用类属性而不是注释?@Pedro,因为无法对属性的变更列表视图进行排序。我想根据注释结果进行排序。我没有看到任何代码表明您尝试了不同的模型定义。我只看到了对get\u queryset()
的更改。好的,所以有效的方法是乘以60000000
(1秒=1000000微秒)。接受,因为你给我指出了正确的方向,请相应地更新答案。谢谢。我应该先让我的孩子们做转化。