如何从Django中的相关表计算日期时间字段的平均差值? [英] How can we calculate average difference of datetime fields from related table in django?

查看:28
本文介绍了如何从Django中的相关表计算日期时间字段的平均差值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个型号演出订单。 并要计算每个任务的Order_Start_TimeOrder_Complete_Time之间的差值的平均值。检查我的代码,它给出以下错误

无法将关键字"Orders"解析到字段中。选项包括:类别、类别_id、详细信息、gig、id、图像、价格、评论、卖家、卖家_id、标题

请帮帮忙!

Models.py(在卖家APP中)

class Gigs(models.Model):
    title = models.CharField(max_length=255)
    category = models.ForeignKey(Categories , on_delete=models.CASCADE)
    images = models.ImageField(blank=True, null = True, upload_to= upload_path)
    price = models.DecimalField(max_digits=6, decimal_places=2)
    details = models.TextField()
    seller = models.ForeignKey(User,default=None, on_delete=models.CASCADE)
 
    @property
    def average_completionTime(self):
        if self._average_completionTime is not None:
            return self._average_completionTime
        return self.gig.aggregate(Avg('order_completed_time'-'order_start_time'))

我认为这里的问题在于平均完成时间,我如何在一个应该在views.py中引用的变量中使用‘ORDER_COMPLETED_TIME’-‘ORDER_START_TIME’

Models.py(买家APP中)

聚焦于项目字段

from seller.models import Gigs
class Orders(models.Model):
    buyer = models.ForeignKey(User,default=None, on_delete=models.CASCADE,related_name='buyer_id')
    seller = models.ForeignKey(User,default=None, on_delete=models.CASCADE,related_name='seller_id')
    item = models.ForeignKey(Gigs,default=None, on_delete=models.CASCADE,related_name='gig')
    payment_method= models.CharField(max_length=10)
    address = models.CharField(max_length=255)
    mobile = models.CharField(max_length=13,default=None)
    quantity = models.SmallIntegerField(default=1)
    status = models.CharField(max_length=13,default='new order')
    order_start_time = models.DateTimeField(default=None)
    order_completed_time = models.DateTimeField(default=None)
    created_at = models.DateTimeField(auto_now_add=True)

Views.py

class RetrieveGigsAPI(GenericAPIView, RetrieveModelMixin):
    def get_queryset(self):
        return Gigs.objects.all().annotate(_average_rating=Avg('orders__time'))
    serializer_class = GigsSerializerWithAvgTime
    permission_classes = (AllowAny,)

    def get(self, request , *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

Serializers.py

class GigsSerializerWithAvgTime(serializers.ModelSerializer):
    average_completionTime = serializers.SerializerMethodField()
    def get_average_completionTime(self, obj):
        return obj.average_completionTime
    class Meta:
        model = Gigs
        fields = ['id','title','category','price','details','seller','images','average_completionTime']

推荐答案

您可以使用其平均完成时间为每个Gig添加批注,如下所示:

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

average_completionTime模型方法中,如果self._average_completionTime没有这样设置,还需要使用F表达式:

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

更新

我无法复制'decimal.Decimal' object has no attribute 'tzinfo'错误。

不知道原因,但根据this答案,您可以尝试使用ExpressionWrapper来避免相同错误,因此:

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

或者正如@Abdul Aziz Barkat提到的,将output_field添加到Avg聚合中,如下所示:

        return Gigs.objects.annotate(
            _average_completionTime=Avg(
                F('gig__order_completed_time') - F('gig__order_start_time'), output_field=DurationField()
            )
        )

这篇关于如何从Django中的相关表计算日期时间字段的平均差值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆