目标是在给定的时间范围内对每个员工的工作时间进行求和和注释。
模型:
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)在给定的日期范围内为每个员工获取工作时间:
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的和注释给每个员工:
queryset.annotate(work_sum=Sum("filtered_work_times__work_delta"))这将导致FieldError:
Cannot resolve keyword 'filtered_work_times' into field. Choices are: first_name, id, work_times从这里怎么走?使用Django 3.1 btw。
发布于 2021-03-14 16:50:58
您应该使用对注解的过滤。我没有尝试过,但我认为下面的代码可能会对您有所帮助:
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"])
)
)发布于 2021-03-14 16:48:24
您不能在查询中使用prefetch_related值,因为预取是单独完成的,因此Django将首先获取当前对象,然后进行查询以获取相关对象,因此您试图引用的字段甚至不是要将其添加到的查询的一部分。
与其这样做,只需在聚合函数中添加一个[Django博士]关键字参数:
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))))https://stackoverflow.com/questions/66626491
复制相似问题