通过外键/相关字段对django queryset进行分组

时间:2013-12-31 05:21:09

标签: django django-models foreign-keys django-queryset

考虑两种模式:

class Question(models.Model):
    ...

class Answer(models.Model):
    question = models.ForeignKey(Question)
    ...

目标是按问题分组答案。我可以想到从Question方面跨越模型关系的一些方法 - 检索所有有任何答案的问题:

Question.objects.annotate(answer_count = Count('answer')) \
                .filter(answer_count__gte=1)

然后我们可以迭代这个QuerySet并使用answer_set来获得特定的答案。

这里的问题是,如果Question表足够大,则此查询非常慢。在大多数问题没有任何答案的情况下,你会变得更加丑陋,最后你会用零填充一个巨大的表格。

从关系的另一端开始,以Answer字段以某种方式对question__id个实例进行分组会很棒。我现在正在处理它的方式是:

answered_questions = [row['question'] for row in 
    Answer.objects.values('question').distinct('question')]
for question in answered_questions:
    answers = Answer.objects.filter(question__id=question)

这显然更快但也很笨拙。通过外键对对象进行分组应该是一项非常常见的任务。有没有更好的方法呢?

1 个答案:

答案 0 :(得分:3)

您可以做的最简单的查询是:

qs = Question.objects.annotate(answer_count = Count('answers')) \
            .filter(answer_count__gte=1).prefetch_related('answers')
# get answer list related to first question
print qs[0].answers.all()

假设您已添加related_name属性:

class Answer(models.Model):
    question = models.ForeignKey(Question, related_name='answers')

我无法想象从数据库中获取所有问题的用例,您通常会对数据或其他内容进行分页,因此慢速查询不应成为问题。