为什么这个 Django 过滤 'annotate' 变量不起作用?
Why doesn't this Django filter by 'annotate' variable work?
我在 Django 中有这个查询集:
obj = Obj.objects.annotate(duration = F('date_end') - F('date_start')).order_by('duration')
以下完美运行:
obj[0].duration
obj.aggregate(Sum('duration'))['duration__sum']
然而,过滤在这种情况下不起作用,即使文档说它应该:
obj = obj.filter( duration__gte = <a_class_datetime.timedelta> ) # doesn't work
obj = obj.filter( duration = 1 ) # doesn't work
这是我遇到的错误:
TypeError: expected string or bytes-like object
我绕过这个问题的方法是遍历数据集——这是一个巨大的数据集。关于为什么这不起作用的任何提示?
过滤时需要使用Python's timedelta
实例,
<b>from datetime import timedelta</b>
obj = obj.filter(duration__gte=<b>timedelta(days=10)</b>)
除此之外,使用 ExpressionWrapper
指定 output_field
以避免不必要的错误。
<b>from django.db import models</b>
# for annotation
annotated_queryset = Foo.objects.annotate(
<b>duration=models.ExpressionWrapper(models.F('date_end') - models.F('date_start'),
output_field=models.DurationField())</b>)
# for filtering
<b>from datetime import timedelta</b>
filtered_queryset = annotated_queryset.filter(duration__gte=<b>timedelta(days=10)</b>)
我在 Django 中有这个查询集:
obj = Obj.objects.annotate(duration = F('date_end') - F('date_start')).order_by('duration')
以下完美运行:
obj[0].duration
obj.aggregate(Sum('duration'))['duration__sum']
然而,过滤在这种情况下不起作用,即使文档说它应该:
obj = obj.filter( duration__gte = <a_class_datetime.timedelta> ) # doesn't work
obj = obj.filter( duration = 1 ) # doesn't work
这是我遇到的错误:
TypeError: expected string or bytes-like object
我绕过这个问题的方法是遍历数据集——这是一个巨大的数据集。关于为什么这不起作用的任何提示?
过滤时需要使用Python's timedelta
实例,
<b>from datetime import timedelta</b>
obj = obj.filter(duration__gte=<b>timedelta(days=10)</b>)
除此之外,使用 ExpressionWrapper
指定 output_field
以避免不必要的错误。
<b>from django.db import models</b>
# for annotation
annotated_queryset = Foo.objects.annotate(
<b>duration=models.ExpressionWrapper(models.F('date_end') - models.F('date_start'),
output_field=models.DurationField())</b>)
# for filtering
<b>from datetime import timedelta</b>
filtered_queryset = annotated_queryset.filter(duration__gte=<b>timedelta(days=10)</b>)