Django ORM DateTimeField ExpressionWrapper QuerySet注释
根据这里的Django文档: 我可以使用ExpressionWrapper进行日期计算。我试着这样使用它:Django ORM DateTimeField ExpressionWrapper QuerySet注释,django,django-orm,Django,Django Orm,根据这里的Django文档: 我可以使用ExpressionWrapper进行日期计算。我试着这样使用它: sprints = Sprint.objects.annotate( duration=models.Case( models.When( Q(started__isnull=False) & Q(done__isnull=False),
sprints = Sprint.objects.annotate(
duration=models.Case(
models.When(
Q(started__isnull=False) &
Q(done__isnull=False),
then=models.Value(
models.ExpressionWrapper(
(models.F('done') - models.F('started')),
output_field=models.DateTimeField()
))
),
models.When(
Q(started__isnull=False) &
Q(done__isnull=True),
then=models.Value(
models.ExpressionWrapper(
(Now() - models.F('started')),
output_field=models.DateTimeField(),
))
),
output_field=models.DateTimeField()
)).values_list('name',
'planned',
'started',
'done',
'duration')
但pytz试图在ExpressionWrapper上进行自动本地化时出错:
Traceback (most recent call last):
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/rest_framework/viewsets.py", line 103, in view
return self.dispatch(request, *args, **kwargs)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/rest_framework/views.py", line 483, in dispatch
response = self.handle_exception(exc)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/rest_framework/views.py", line 443, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/rest_framework/views.py", line 480, in dispatch
response = handler(request, *args, **kwargs)
File "/home/phirt/src/core3/src/backend/portal/views/api/transformation.py", line 766, in get_sprint_data_csv
for sprint in sprints:
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/db/models/query.py", line 272, in __iter__
self._fetch_all()
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/db/models/query.py", line 1179, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1011, in apply_converters
value = converter(value, expression, connection)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/db/backends/mysql/operations.py", line 247, in convert_datetimefield_value
value = timezone.make_aware(value, self.connection.timezone)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/utils/timezone.py", line 269, in make_aware
return timezone.localize(value, is_dst=is_dst)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/pytz/__init__.py", line 226, in localize
if dt.tzinfo is not None:
AttributeError: 'str' object has no attribute 'tzinfo'
实际上,在pytz中传递给localize
的dt
参数是一个字符串,它正是我的ExpressionWrapper表达式:ExpressionWrapper(F(done)-F(start))
我怎样才能做到这一点
编辑:以下是sprint模型:
class Sprint(BaseModel):
name = models.CharField(max_length=100)
planned = models.DateTimeField(null=True, blank=True)
started = models.DateTimeField(null=True, blank=True)
done = models.DateTimeField(null=True, blank=True)
state = models.CharField(max_length=20, verbose_name='State')
start_planned = models.DateTimeField(blank=True, null=True,
verbose_name='Start Planned')
start_latest = models.DateTimeField(blank=True, null=True,
verbose_name='Start Latest')
enforce_start = models.BooleanField(default=False,
verbose_name='Enforce Start')
class Meta:
ordering = ["name"]
verbose_name = "Sprint"
def __str__(self):
return f'<Sprint name="{self.name}">'
class Sprint(基本模型):
name=models.CharField(最大长度=100)
计划=模型.DateTimeField(null=True,blank=True)
started=models.DateTimeField(null=True,blank=True)
done=models.DateTimeField(null=True,blank=True)
state=models.CharField(最大长度=20,详细名称='state')
start\u planned=models.DateTimeField(空白=True,空=True,
详细的(名称为“开始计划”)
start_latest=models.DateTimeField(空白=True,空=True,
详细信息(name='Start Latest')
强制_start=models.BooleanField(默认值=False,
详细的(名称=“强制开始”)
类元:
排序=[“名称”]
verbose_name=“Sprint”
定义(自我):
返回f“”
我通过将查询注释更改为以下内容使其正常工作:
sprints = Sprint.objects.annotate(
duration=models.Case(
models.When(
Q(started__isnull=False) &
Q(done__isnull=False),
then=(models.F('done') - models.F('started')),
),
models.When(
Q(started__isnull=False) &
Q(done__isnull=True),
then=(Now() - models.F('started')),
),
output_field=models.DurationField()
)).values_list('name',
'planned',
'started',
'done',
'duration')
你能添加
Sprint
模型吗?我已经编辑了这个问题,将模型包括在内,这是一个独特的场景,但是你的问题(和答案)今天碰巧帮助了我,谢谢你,先生@Patrick我正在做一件非常类似的事情,得到了这个错误-案例类型interval和integer无法匹配
。你在任何时候都面对过吗?这个错误的根源似乎是,对于第一个“如果”,它将天数减法乘以interval 1days
,我猜这就像是强制转换,但对于另一个“如果”则不是这样。@user2880391您使用的类型似乎与I不同(interval而不是datetime)。尝试将值强制转换为通用类型,既可以是整数,也可以是间隔,也可以是日期时间。