【问题标题】:django.core.exceptions.FieldError: Cannot resolve keyword 'duration' into field when trying to select a property fielddjango.core.exceptions.FieldError:尝试选择属性字段时无法将关键字“持续时间”解析为字段
【发布时间】:2022-01-25 05:27:33
【问题描述】:

关于这个特定错误有很多问题,但没有一个是由于尝试从序列化程序中选择属性字段引起的,下面是我的代码

 # 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 ProjectActivity(models.Model):
    id = models.AutoField(primary_key=True)
    description = models.TextField(blank=False, null=False, 
     max_length=400, default="")
    project = models.ForeignKey(to=Project, 
    on_delete=models.CASCADE)
    user = models.ForeignKey(to=Employee, on_delete=models.CASCADE)
    start_time = models.DateTimeField(auto_now_add=True)
    end_time = models.DateTimeField(blank=True, null=True)

    @property
    def duration(self):
        """
        get the duration of the activity

        Returns:
            timedelta: duration of the activity
        """
        if self.is_running:
            sec = datetime.now(timezone.utc) - self.start_time
            return str(timedelta(seconds=round(sec.total_seconds())))
        else:
            sec = self.end_time - self.start_time
            return str(timedelta(seconds=round(sec.total_seconds())))
          

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

Just a background to my problem here: i have the below response

    [
        {
            "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
        }
    ]

我想对持续时间进行计算,但持续时间字段不是我的模型字段的一部分,而是一个公正的属性。持续时间值是从模型的持续时间属性中获取的,我想从响应中计算总持续时间。

现在我发现运行计算很困难

【问题讨论】:

  • 要在queryset 中使用它,您必须使用F() annotations annotate 它。
  • 你想做什么?
  • 显示 ProjectActivity 模型?
  • @IainShelvington 我已经做到了。
  • @shivankgtm 我想总结所有的持续时间值

标签: python django django-rest-framework


【解决方案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'))

【讨论】:

  • 我已经尝试过您的解决方案,但出现以下错误 AttributeError: Got AttributeError when trying to get a value for field project on serializer ProjectActivitySerializer.序列化程序字段可能命名不正确,并且与 str 实例上的任何属性或键都不匹配。原始异常文本是:“str”对象没有属性“project”。
  • @user15317824 这是在您的GetTotalProjectActivityTime 视图中吗?如果这个视图只应该返回一个总持续时间,那么这个视图不应该是一个列表 api 视图,并且应该有一个不同的序列化器来返回正确的字段
  • 这是一个 ListAPIView,请问我应该使用什么类型的视图?
  • 我可以用 APIVIEW 代替 LIstApiView 吗?
猜你喜欢
  • 1970-01-01
  • 2020-11-08
  • 2014-04-15
  • 1970-01-01
  • 2021-09-17
  • 2017-11-08
  • 1970-01-01
  • 2016-05-10
  • 1970-01-01
相关资源
最近更新 更多