Почему этот фильтр Django по переменной annotate не работает? - PullRequest
2 голосов
/ 10 октября 2019

У меня есть этот набор запросов в 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: ожидаемая строка или байтовоподобный объект

Мой способ обойти эту проблемуэто перебрать набор данных - который огромен. Любые советы, почему это не работает?

1 Ответ

1 голос
/ 10 октября 2019

Вам нужно использовать экземпляр Python 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>)
...