【问题标题】:Django: how to annotate based on another annotation, or perform operations on an annotationDjango:如何基于另一个注解进行注解,或者对一个注解执行操作
【发布时间】:2011-11-21 16:27:07
【问题描述】:

所以我正在制作一些可以组织学校日程的东西。有问题的学校是这样组织的,班级呆在同一个房间,老师移动,每天的时间表都不一样,而且不是所有的老师或班级都在同一时间,有些的老师对教学非常挑剔。

我有这些模型:

class Teacher(models.Model):
    christian_name = models.CharField(max_length=200)
    family_name = models.CharField(max_length=200)
    ...

class TeacherAvailableHour(models.Model):
    teacher = models.ForeignKey('Teacher')

class Requirement(models.Model):
    ...
    teacher = models.ForeignKey('Teacher')
    per_week = models.PositiveIntegerField()
    ...

所以我想做的事情是首先为最挑剔的老师制定时间表,即他们可以教的时间(总“TeacherAvailableHour”)与他们需要教的小时数之间的比率最小的那些(所有老师的“Requirement.per_week”总和)。

换句话说,我需要“order_by”那个比率。我想不出该怎么做。试过这个:

Teachers=Teacher.objects.annotate(availability=(Count('teacheravailablehour') / Sum('requirement__per_week')).order_by('availability')

当然,这会导致错误。我也尝试过类似双重注释的方法:

Teachers=Teacher.objects.annotate(availability=Count('teacheravailablehour')).annotate(required=Sum('requirement__per_week')).annotate(availRatio=(('availability') / ('required')).order_by('-availRatio')

最好的方法是什么?这甚至可能吗?

【问题讨论】:

    标签: django aggregate annotate


    【解决方案1】:

    您无法使用 annotate 方法计算这样的比率。您需要使用 QuerySet API 提供的extra() 方法。虽然不建议使用 extra 进行查找,因为它们不能跨数据库引擎移植,但有时它们是执行此类复杂查询的最佳(或唯一)选择。

    假设您引用的所有模型都在一个名为 schedules 的应用程序中,并且您没有使用模型元类中的 db_table 属性修改表名,查找将是像这样:

    availability_sql = "(select count(*) from schedules_teacheravailablehour where schedules_teacheravailablehour.teacher_id=schedules_teacher.id) * 1.0"
    required_hrs_sql = "(select sum(per_week) from schedules_requirement where schedules_requirement.teacher_id=schedules_teacher.id)"
    Teacher.objects.extra(select={"ratio":"%s/%s" %(availability_sql, required_hrs_sql)}).order_by("-ratio")
    

    【讨论】:

      猜你喜欢
      • 2019-10-26
      • 2011-11-22
      • 1970-01-01
      • 2019-05-27
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多