Python Django:具有相同条目的组的QuerySet
我的目标是在一项具体的调查中,按照显著性从高到低排列每个问题的前10个“实体”。 调查有几个问题。每个问题都有几个答案。每个答案可以有几个实体(有时相同的Python Django:具有相同条目的组的QuerySet,python,django,Python,Django,我的目标是在一项具体的调查中,按照显著性从高到低排列每个问题的前10个“实体”。 调查有几个问题。每个问题都有几个答案。每个答案可以有几个实体(有时相同的名称(CharField),有时不同的名称s)。实体按每个问题的名称字段分组 我认为以下最终结果是有意义的: [ 5: # question.pk [ { 'name': 'Leonardo Di Caprio', 'count': 4, # E.g. answ
名称
(CharField),有时不同的名称
s)。实体按每个问题的名称
字段分组
我认为以下最终结果是有意义的:
[
5: # question.pk
[
{
'name': 'Leonardo Di Caprio',
'count': 4, # E.g. answer__pk = 1, answer__pk = 1, answer__pk = 2, answer__pk = 3. Leonardo Di Caprio was mentioned twice in answer_pk 1 and therefore has entries.
'salience': 3.434 # Sum of all 4 entities
},
{
'name': 'titanic',
'count': 5,
'salience': 1.12
},
{
'name': 'music',
'count': 3,
'salience': 1.12
}
],
3: # question.pk
[
{
'name': 'Leonardo Di Caprio',
'count': 5,
'salience': 1.5
},
{
'name': 'titanic',
'count': 4,
'salience': 1.12
},
{
'name': 'music',
'count': 2,
'salience': 1.12
}
],
]
现在我正努力为我想要的结果编写正确的查询集。我的观点是,我可能必须使用.values()
和.annotate()
。但我的成绩与我的目标相差甚远
这里是my models.py:
class Entity(TimeStampedModel):
name = models.CharField()
type = models.CharField()
salience = models.FloatField()
sentiment_magnitude = models.FloatField()
sentiment_score = models.FloatField()
language = models.CharField()
answer = models.ForeignKey(
Answer, on_delete=models.CASCADE, related_name="entities"
)
class Answer(TimeStampedModel):
question = models.ForeignKey(
"surveys.Question", on_delete=models.CASCADE, related_name="answers"
)
response = models.ForeignKey()
answer = models.TextField()
class Question(TimeStampedModel):
survey = models.ForeignKey(
"surveys.Survey", on_delete=models.CASCADE, related_name="questions"
)
title = models.CharField(max_length=100, verbose_name=_("Title"))
focus = models.CharField()
class Response(TimeStampedModel):
survey = models.ForeignKey(
"surveys.Survey", on_delete=models.CASCADE, related_name="responses"
)
order = models.ForeignKey()
attendee = models.ForeignKey()
total_time = models.PositiveIntegerField()
ip_address = models.GenericIPAddressField()
language = models.CharField()
class Survey(TimeStampedModel):
id = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4)
event = models.ForeignKey()
template = models.CharField()
这里是我迄今为止所尝试的。但这似乎与我的目标相去甚远:
questions = self.request.event.surveys.get_results(
settings.SURVEY_PRE_EVENT
)
for question in questions:
print("------")
print(question.pk)
answers = question.answers.all()
for answer in answers:
print(
answer.entities.values("name")
.annotate(count=Count("name"))
.annotate(salience=Sum("salience"))
)
以下是输出:
------
33
<QuerySet [{'name': 'people', 'count': 1, 'salience': 1.0}]>
<QuerySet [{'name': 'income', 'count': 1, 'salience': 1.0}]>
<QuerySet [{'name': 'incomes', 'count': 2, 'salience': 1.26287645101547}]>
------
33
我不能完全确定我是否正确理解了您的问题,但您可能正在寻找类似
Question.objects.values("answers__entities__name").annotate(
salience=Sum("answers__entities__salience"),
count=Count("answers"),
)
免责声明:
我还没有测试过这一点,我可能是错的,但这就是我要开始玩的东西
此外,您可能会发现这一点很有用:您可以循环问题,以便为每个问题创建一个列表:
Entity.objects.filter(answer__question=question).values('name').annotate(count=Count('pk')).annotate(total_salience=Sum('salience'))
或者,如果您想在一个查询集中设置所有查询,请先按问题分组(pk):
这将生成一个列表,而不是一个按问题嵌套的列表,但您可以稍后在python中重新组合该列表以嵌套每个问题的实体。请显示您尝试过但不起作用的内容。我在末尾添加了它。尝试每个问题:
Entity.objects.filter(answer\u question=question)。value('name')。annotate(count=count('pk')。annotate(总突出度=总和(“突出度”)
。您当前的代码一次只获取一个答案,而不是获取与问题相关的所有实体。这似乎很有效!也许我尝试得太多了,但现在它是针对每个问题的附加查询。我希望我能以某种方式将其合并为针对所有问题的一个查询,这样我就不必经常访问数据库。这是一个gRET文章,谢谢。我目前采用dirkgroten从实体级别编写的方法。但我相信这是另一种解决方案。
Entity.objects.values('answer__question__pk', 'name').annotate(count=Count('pk')).annotate(total_salience=Sum('salience'))