首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django:无法使用预取计算属性进行注释

Django:无法使用预取计算属性进行注释
EN

Stack Overflow用户
提问于 2021-03-14 15:50:53
回答 2查看 593关注 0票数 2

目标是在给定的时间范围内对每个员工的工作时间进行求和和注释。

模型:

代码语言:javascript
复制
class Employee(models.Model):
    first_name = models.CharField(max_length=64)

class WorkTime(models.Model):
    employee = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name="work_times")

    work_start = models.DateTimeField()
    work_end = models.DateTimeField()
    work_delta = models.IntegerField(default=0)

    def save(self, *args, **kwargs):
        self.work_delta = (self.work_end - self.work_start).seconds
        super().save(*args, **kwargs)

在给定的日期范围内为每个员工获取工作时间:

代码语言:javascript
复制
queryset = Employee.objects.prefetch_related(
                Prefetch(
                    'work_times',
                    queryset=WorkTime.objects.filter(work_start__date__range=("2021-03-01", "2021-03-15"]))
                        .order_by("work_start"),
                    to_attr="filtered_work_times"
                )).all()

试图将work_delta的和注释给每个员工:

代码语言:javascript
复制
queryset.annotate(work_sum=Sum("filtered_work_times__work_delta"))

这将导致FieldError:

代码语言:javascript
复制
Cannot resolve keyword 'filtered_work_times' into field. Choices are: first_name, id, work_times

从这里怎么走?使用Django 3.1 btw。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-03-14 16:50:58

您应该使用对注解的过滤。我没有尝试过,但我认为下面的代码可能会对您有所帮助:

代码语言:javascript
复制
from django.db.models import Sum, Q

Employee.objects.annotate(
    work_sum=Sum(
        'work_times__work_delta',
        filter=Q(work_times__work_start__date__range=["2021-03-01", "2021-03-15"])
    )
)
票数 2
EN

Stack Overflow用户

发布于 2021-03-14 16:48:24

您不能在查询中使用prefetch_related值,因为预取是单独完成的,因此Django将首先获取当前对象,然后进行查询以获取相关对象,因此您试图引用的字段甚至不是要将其添加到的查询的一部分。

与其这样做,只需在聚合函数中添加一个[Django博士]关键字参数:

代码语言:javascript
复制
from django.db.models import  Q


start_date = datetime.date(2021, 3, 1)
end_date = datetime.date(2021, 3, 15)

result = queryset.annotate(work_sum=Sum("work_times__work_delta", filter=Q(work_times__work_start__date__range=(start_date, end_date))))
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66626491

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档