use*_*126 5 django aggregate annotate
所以我正在做一些组织学校日程安排的事情.有问题的学校的组织方式是课程在同一个房间里,老师一起移动,时间表每天都不同,并不是所有的老师或班级同时在建筑物内,有些老师们教他们的时候非常挑剔.
我有这些模型:
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()
...
Run Code Online (Sandbox Code Playgroud)
所以我要做的就是先为最挑剔的老师制定一个时间表,即他们可以教的时间比例最小的教师(总"教师可用的时间")和他们需要教授的小时数(总和)所有老师的"Requirement.per_week").
换句话说,我需要"order_by"这个比例.我想不出怎么做.试过这个:
Teachers=Teacher.objects.annotate(availability=(Count('teacheravailablehour') / Sum('requirement__per_week')).order_by('availability')
Run Code Online (Sandbox Code Playgroud)
当然,这会因错误而爆炸.我也试过像双重注释的东西:
Teachers=Teacher.objects.annotate(availability=Count('teacheravailablehour')).annotate(required=Sum('requirement__per_week')).annotate(availRatio=(('availability') / ('required')).order_by('-availRatio')
Run Code Online (Sandbox Code Playgroud)
做这个的最好方式是什么?这甚至可能吗?
您无法使用 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")
Run Code Online (Sandbox Code Playgroud)