Django抱怨在子查询中使用查询时,必须在子查询中使用查询

时间:2018-09-17 18:22:11

标签: python django

对于名为QuerySet的模型,我具有以下自定义Program方法:

def with_volunteer_stats(self):
    from programs.models import Session
    volunteers_needed = ExpressionWrapper(
        F('num_student_seats') / F('student_volunteer_ratio'),
        output_field=models.IntegerField())

    sessions = (
        Session.objects.filter(program_id=OuterRef('pk'))
        .annotate(num_volunteers=Count('volunteer_attendances__volunteer', distinct=True))
        .order_by('num_volunteers')
    )
    qs = self.annotate(
        volunteers_needed=volunteers_needed,
        least_volunteers=Subquery(sessions.values('num_volunteers')[0])
    ).annotate(
        remaining_volunteers_needed=(F('volunteers_needed') - F('num_volunteers'))
    )
    return qs

运行此程序时,出现异常:

ValueError: This queryset contains a reference to an outer query and may only be used in a subquery.

回溯显示使用Subquery对行进行评估时发生的异常。这与Django文档中有关如何使用Subquery的示例非常接近。有什么想法我做错了吗?

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。现在我有了一个更好的主意,我想为后代添加一个解释。

问题似乎在这里:

Subquery(sessions.values('num_volunteers')[0])
#                                         ^^^

目的是为子查询提供QuerySet,但实际上发生的是项目访问器过早强制执行评估。换句话说,这将产生一个QuerySet:

sessions.values('num_volunteers')

但这迫使评估产生一个对象:

sessions.values('num_volunteers')[0]

这意味着sessions.values('num_volunteers') QuerySet在子查询的上下文之外进行评估。因此,如果不清楚,则错误消息是正确的。

根据以下mfrackowiak的评论,Django文档提供了有关如何limit the subquery to a single row的建议:

sessions.values('num_volunteers')[:1]