我有一个查询,可检索20个问题。然后,查询应在查询集中添加另一列或数据,以指示用户已回答的选择。因此,总共有4个模型,包括一个用户模型。
class Question(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.CharField(max_length=200)
total_votes = models.IntegerField(default=0)
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice = models.CharField(max_length=120)
vote_count = models.IntegerField(default=0)
class Voting(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
choice = models.ForeignKey(Choice, on_delete=models.CASCADE)
查询
Question.objects.filter(
Q(user=3))[:20]
当我这样做时,它不起作用:
Question.objects.filter(Q(user=1)).annotate(which_answer= filter(choice__question=3, user=1))[:20]
我得到TypeError: filter() does not take keyword arguments
如何在此查询中添加另一列以显示用户选择了哪个选项?
答案 0 :(得分:1)
注释将需要如下所示(如果用户ID = 1):
choice_query = Subquery(Choice.objects.filter(question=OuterRef('pk')).values('choice')[:1], output_field=models.CharField())
Question.objects.filter(user=1).annotate(which_answer=choice_query)[:20]
您编写了一个子查询,该子查询根据要注释的问题和用户过滤选择对象,仅选择1(假设仅应为1)并将该选择值输出到char字段,然后对此进行注释子查询。
只是一个旁注:此处似乎不需要Q表达式。
不确定这里用的是什么,但是如果您使用序列化程序,并且只在主查询中添加一个select related子句,而不必理会注解,则可能还会遇到更多运气或更好的性能。
编辑:经过讨论,我相信您真正想要的是用户的VOTE,它指向他们的选择。看起来像这样(再次是用户ID = 1):
vote_query = Subquery(Vote.objects.filter(question=OuterRef('pk'), user=1).values('choice')[:1], output_field=models.IntegerField())
Question.objects.filter(user=1).annotate(which_answer=vote_query)[:20]
此查询会将所选用户的ID输出到which_answer注释。