[Answered ]-How can we calculate average difference of datetime fields from related table in django?

1๐Ÿ‘

โœ…

You can annotate each gig with its average completion time like this:

    def get_queryset(self):
        return Gigs.objects.annotate(
            _average_completionTime=Avg(
                F('gig__order_completed_time') - F('gig__order_start_time')
            )
        )

In your average_completionTime model method, you also need to use F expressions if self._average_completionTime is not set so:

    @property
    def average_completionTime(self):
        if getattr(self, '_average_completionTime', None):
            return self._average_completionTime
        return self.gig.aggregate(Avg(F('order_completed_time') - F('order_start_time')))

UPDATE:

Iโ€™m not able to reproduce the 'decimal.Decimal' object has no attribute 'tzinfo' error.

No clue why, but based on this answer, you can try to use ExpressionWrapper to avoid that same error, so:

from django.db.models import DurationField, ExpressionWrapper, F


class GigsSerializerWithAvgTime(serializers.ModelSerializer):
    def get_queryset(self):
        return Gigs.objects.annotate(
            _average_completionTime=Avg(
                ExpressionWrapper(F('gig__order_completed_time') - F('gig__order_start_time'), output_field=DurationField())
            )
        )

or as @Abdul Aziz Barkat has mentioned, add the output_field to the Avg aggregate like this:

        return Gigs.objects.annotate(
            _average_completionTime=Avg(
                F('gig__order_completed_time') - F('gig__order_start_time'), output_field=DurationField()
            )
        )
๐Ÿ‘คBrian Destura

0๐Ÿ‘

An F() object represents the value of a model field, it refers to model field values and perform database operations using them. for more details, https://docs.djangoproject.com/en/3.2/ref/models/expressions/#f-expressions

from django.db.models import F

let say queryset = Gigs.objects.all()

#you add '_average_completionTime' in the queryset
queryset = queryset.annotate(_average_completionTime=Avg(F('gig__order_completed_time') - F('gig__order_start_time'))

Leave a comment