2

I have this queryset in Django:

obj = Obj.objects.annotate(duration = F('date_end') - F('date_start')).order_by('duration')

The following works perfectly:

obj[0].duration

obj.aggregate(Sum('duration'))['duration__sum']

However filtering doesn't work in this case even though documentation says that it should:

obj = obj.filter( duration__gte = <a_class_datetime.timedelta> )  # doesn't work
obj = obj.filter( duration = 1 )   # doesn't work

This is the error I am getting:

TypeError: expected string or bytes-like object

My way to bypass this issue is to loop through the dataset - which is huge. Any tips as to why this is not working?

1 Answer 1

2

You need to use Python's timedelta instance while filtering,

from datetime import timedelta

obj = obj.filter(duration__gte=timedelta(days=10))

Apart from that, use ExpressionWrapper to specify the output_field so that you can avoid unwanted errors.

from django.db import models

# for annotation
annotated_queryset = Foo.objects.annotate(
    duration=models.ExpressionWrapper(models.F('date_end') - models.F('date_start'),
                                      output_field=models.DurationField()))

# for filtering
from datetime import timedelta

filtered_queryset = annotated_queryset.filter(duration__gte=timedelta(days=10))
Sign up to request clarification or add additional context in comments.

1 Comment

ExpressionWrapper with DurationField in this case works like a charm. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.