0

我有以下型号:

class Question(models.Model):
    question = models.CharField(max_length=100)
    detail = models.TextField(null=True, blank=True)

class PossibleAnswers(models.Model):
    question = models.ForeignKey(Question)
    value = models.CharField(max_length=200)

class Answer(models.Model):
    question = models.ForeignKey(Question)
    value = models.CharField(max_length=200)

每个都由Question用户PossibleAnswers定义。例如:问题 - 什么是最好的水果?可能的答案 - 苹果、橙子、葡萄。现在其他用户可以Answer将他们的回答限制为PossibleAnswers.

我遇到的问题是计算每个Answer. 有多少人选择 Apple vs Orange vs Grapes?

Question.answer_set.filter(value="Grapes").count()返回所有葡萄答案的计数,但是如果您不知道过滤条件(在这种情况下为葡萄)会是什么?由于用户定义了答案选项,并定义了有多少不同的选项,那么您将如何获得每个答案选项的响应计数?

4

3 回答 3

2

首先我会改变你的模型。您的架构未标准化。这意味着您将相同的信息(答案的文本)保存在多个位置。这本身被认为是一件坏事,但也使设计正确的查询变得更加困难。这就是我认为你的模型应该是这样的:

class Question(models.Model):
    question = models.CharField(max_length=100)
    detail = models.TextField(null=True, blank=True)

class PossibleAnswer(models.Model):
    question = models.ForeignKey(Question)
    value = models.CharField(max_length=200)

class Answer(models.Model):
    possible_answer = models.ForeignKey(PossibleAnswers)

每次用户为可能的答案投票时,您都会添加一个Answer引用该可能答案的新模型。您还可以向Answer模型添加其他字段,例如引用用户投票的外键。

然后,您将使用以下代码获取问题的信息(即每个可能的答案有多少实际答案)foo

PossibleAnswer.objects.filter(question=foo).annotate(Count('answer'))
于 2013-10-09T19:18:05.733 回答
0

这对你有帮助吗?

q = Question.objects.get(pk=1)
[{v: q.answer_set.filter(value=v).count()} 
           for v in [pa.value for 
                       pa in q.possibleanswers_set.all()]]

它将为问题对象 q 存在的每个可能的答案返回一个 {'possible_answer': 'count'} 的字典。

但是,如果您打算在更大范围内使用它(例如对于所有Question 对象),这并不是最有效的做事方式,在这种情况下,您最好使用聚合(在此处阅读)。

于 2013-10-09T18:18:55.900 回答
0

您需要一个聚合查询

from django.db.models import Count
Question.objects.annotate(Count('answer'))
于 2013-10-09T18:30:11.120 回答