是否可以在注释中进行过滤?
在我看来这样的事情(实际上并不起作用)
Student.objects.all().annotate(Count('attendance').filter(type="Excused"))
由此产生的表格将让每个学生都有理由缺席.查看文档过滤器只能在注释之前或之后进行,否则将无法产生所需的结果.
解决方法就是这样
for student in Student.objects.all():
student.num_excused_absence = Attendance.objects.filter(student=student, type="Excused").count()
Run Code Online (Sandbox Code Playgroud)
这可以工作,但在实际应用程序中执行很多查询,这可能会变得不切实际.我认为这种类型的语句在SQL中是可行的,但如果可能的话,我更愿意继续使用ORM.我甚至尝试过两个单独的查询(一个用于所有学生,另一个用于获得总数)并将它们与|组合.组合改变了总数:(
我在这里使用额外的SQL解决了出勤问题.
gor*_*onc 15
从Django 1.8开始,您可以直接在ORM中执行此操作:
students = Student.objects.all().annotate(num_excused_absences=models.Sum(
models.Case(
models.When(absence__type='Excused', then=1),
default=0,
output_field=models.IntegerField()
)))
Run Code Online (Sandbox Code Playgroud)
答案改编自同一主题的另一个SO问题
我没有测试上面的示例,但确实在我自己的应用程序中完成了类似的操作.
小智 5
你是对的 - django不允许你过滤被计数的相关对象,也不允许过滤器应用于主要对象,因此在过滤后排除那些没有相关对象的主要对象.
但是,在一些抽象泄漏中,您可以使用值查询来计算组.
所以,我在字典中收集缺席,并在循环中使用它.像这样的东西:
# a query for students
students = Students.objects.all()
# a query to count the student attendances, grouped by type.
attendance_counts = Attendence(student__in=students).values('student', 'type').annotate(abs=Count('pk'))
# regroup that into a dictionary {student -> { type -> count }}
from itertools import groupby
attendance_s_t = dict((s, (dict(t, c) for (s, t, c) in g)) for s, g in groupby(attendance_counts, lambda (s, t, c): s))
# then use them efficiently:
for student in students:
student.absences = attendance_s_t.get(student.pk, {}).get('Excused', 0)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8538 次 |
| 最近记录: |