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'))