Django.core.exceptions.FieldError: Невозможно преобразовать ключевое слово 'duration' в поле при попытке выбрать поле свойства

здесь много вопросов по этой конкретной ошибке, но ни один не вызван попыткой выбрать поле свойства из сериализатора, ниже приведен мой код

# seriliazer.py
class ProjectActivitySerializer(serializers.ModelSerializer):
    is_running = serializers.ReadOnlyField()
    duration = serializers.ReadOnlyField() # i am trying to select this particular field to perform some calculation
    
    class Meta:
        model = ProjectActivity
        fields = '__all__'

class GetTotalProjectActivityTime(ListAPIView):
    """
    
    """
    serializer_class = ProjectActivitySerializer
    permission_classes = (IsAuthenticated, IsOwner|IsAdminUser) # protect the endpoint


    def get_queryset(self):
        return ProjectActivity.objects.filter(user=self.kwargs['user'], project__id=self.kwargs['project']).values('duration')
        

Просто предыстория моей проблемы: у меня есть следующий ответ

[
    {
        "id": 1,
        "is_running": true,
        "duration": "2 days, 5:43:26",
        "description": "worked on developing dashboard endpoint",
        "start_time": "2021-12-22T11:40:49.452935Z",
        "end_time": null,
        "project": 1,
        "user": 1
    }
]

Я хочу выполнить вычисление продолжительности, но поле продолжительности не является частью поля моей модели, а просто свойством.

теперь мне трудно выполнить расчет

Сначала измените свойство duration на использование cached_property, это позволит вам создать аннотацию с тем же именем и не получить конфликт, когда аннотированное значение будет установлено на объекте.

from django.utils.functional import cached_property
from django.utils.timezone import now

class ProjectActivity(models.Model):

    @cached_property
    def duration(self):
        return (self.end_time or now()) - self.start_time

Теперь мы можем аннотировать кверисет с помощью duration, используя следующее

from django.db.models import F
from django.db.models.functions import Coalesce, Now

queryset = ProjectActivity.objects.annotate(
    end_or_now=Coalesce('end_time', Now()))
).annotate(
    duration=F('end_or_now') - F('start_time')
)

Эта аннотация может затем использоваться в дальнейших аннотациях, фильтрах, агрегатах и т.д.

from django.db.models import Sum

queryset.aggregate(total_duration=Sum('duration'))
Вернуться на верх