如何在查询集中创建具有过滤值的另一列

时间:2018-11-20 20:47:05

标签: python django django-queryset

我有一个查询,可检索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

如何在此查询中添加另一列以显示用户选择了哪个选项?

1 个答案:

答案 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注释。