0

基本上我遇到的问题是:我需要一个选项或替代方法来过滤联合查询集上的注释字段。

我有以下简化模型设置:

class Course(Model):
    groups = ManyToManyField(through=CourseAssignment)


class CourseAssignment(Model):
    course = ForeignKey(Course)
    group = ForeignKey(Group)
    teacher = ForeignKey(Teacher)


class Lesson(Model):
    course = ForeignKey(Course, related_name='lessons')


class AssignmentProgress(Model):
    lesson = ForeignKey(related_name='progresses')
    course_assignment = ForeignKey(CourseAssignment)
    student = ForeignKey(Student)
    group = ForeignKey(Group)
    status = CharField(choices=(
                ('on_check', 'On check'), 
                ('complete', 'Complete'),
                ('assigned', 'Assigned'),
            ))
    deadline = DateTimeField()
    checked_date = DateTimeField()

我需要显示按课程分组的作业进度统计数据和分配课程的组。这是我的初始查询集,请注意课程在最终结果中重复,不同之处在于带注释的数据:

def annotated_lessons_queryset():
    lessons = None
    for course_assignment in CourseAssignment.objects.all():
        qs = Lesson.objects.filter(
            course=course_assignment.course
        ).annotate(
            completed_progresses=Count(
                'progresses',
                filter=Q(group=course_assignment.group),
                output_field=IntegerField()
            ),
            on_check=Exists(
                AssignmentProgress.objects.filter(
                    lesson=OuterRef('id'), group=course_assignment.group, status='on_check'
                )
            )
        )
        lessons = qs if lessons is None else lessons.union(qs)
    return lessons

我佳能使用| 此处为 OR 运算符,因为它仅返回不同的课程值。到目前为止,这一直有效,直到我尝试过滤所有带有注释状态 on_check 的课程:

qs = annotated_lessons_queryset().filter(on_check=True)

失败并出现错误:

raise NotSupportedError(
django.db.utils.NotSupportedError: Calling QuerySet.filter() after union() is not supported.

请提出解决方法或其他方法来过滤此查询集。

4

1 回答 1

0

我还没有将其拉入并尝试过,但是正如错误消息所述,您必须最后使用 union() 。这有点复杂,因为此查询集中的“课程可以重复”。所以我建议使用列表理解来获得你需要的东西。

qs = annotated_lessons_queryset()
filtered = [lesson for lesson in qs if lesson.on_check]
于 2021-11-05T10:59:07.657 回答